summaryrefslogtreecommitdiff
path: root/modules/organize
diff options
context:
space:
mode:
Diffstat (limited to 'modules/organize')
-rw-r--r--modules/organize/controllers/organize.php528
-rw-r--r--modules/organize/css/organize.css203
-rw-r--r--modules/organize/helpers/organize.php94
-rw-r--r--modules/organize/helpers/organize_event.php4
-rw-r--r--modules/organize/helpers/organize_task.php131
-rw-r--r--modules/organize/helpers/organize_theme.php27
-rw-r--r--modules/organize/js/organize.js662
-rw-r--r--modules/organize/js/organize_init.js29
-rw-r--r--modules/organize/views/organize.html.php53
-rw-r--r--modules/organize/views/organize_album.html.php17
-rw-r--r--modules/organize/views/organize_button_pane.html.php50
-rw-r--r--modules/organize/views/organize_dialog.html.php45
-rw-r--r--modules/organize/views/organize_edit.html.php14
-rw-r--r--modules/organize/views/organize_thumb_grid.html.php26
-rw-r--r--modules/organize/views/organize_tree.html.php19
15 files changed, 212 insertions, 1690 deletions
diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php
index 898be509..3a81ef4f 100644
--- a/modules/organize/controllers/organize.php
+++ b/modules/organize/controllers/organize.php
@@ -18,523 +18,55 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Organize_Controller extends Controller {
- private static $_MICRO_THUMB_SIZE = 90;
- private static $_MICRO_THUMB_PADDING = 5;
-
- function index($item_id=1) {
+ function dialog($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.html");
- $v->root = $root;
- $v->item = $item;
- $v->album_tree = $this->tree($item, $root);
- $v->button_pane = new View("organize_button_pane.html");
+ $v = new View("organize_dialog.html");
+ $v->title = $item->title;
+ $parents = array();
+ foreach ($item->parents() as $parent) {
+ $parents[$parent->id] = 1;
+ }
+ $parents[$item->id] = 1;
+
+ $v->album_tree = $this->_tree($root, $parents);
+ $v->micro_thumb_grid = $this->_get_micro_thumb_grid($item, 0);
print $v;
}
- function content($item_id) {
+ function content($item_id, $offset) {
$item = ORM::factory("item", $item_id);
access::required("view", $item);
access::required("edit", $item);
+ print $this->_get_micro_thumb_grid($item, $offset);
+ }
- $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) {
$v = new View("organize_thumb_grid.html");
- $v->children = $item->children($page_size, $offset);
- $v->thumbsize = self::$_MICRO_THUMB_SIZE;
- $v->padding = self::$_MICRO_THUMB_PADDING;
+ $v->item = $item;
$v->offset = $offset;
-
- print json_encode(array("count" => $v->children->count(),
- "data" => $v->__toString()));
+ return $v;
}
- function header($item_id) {
- $item = ORM::factory("item", $item_id);
- access::required("view", $item);
- access::required("edit", $item);
-
- print json_encode(
- array("title" => p::purify($item->title),
- "description" => empty($item->description) ? "" : p::purify($item->description)));
- }
-
- function tree($item, $parent) {
- access::required("view", $item);
- access::required("edit", $item);
-
- $albums = ORM::factory("item")
- ->where(array("parent_id" => $parent->id, "type" => "album"))
- ->orderby(array("title" => "ASC"))
- ->find_all();
-
- $v = new View("organize_album.html");
- $v->album = $parent;
- $v->selected = $parent->id == $item->id;
+ private function _tree($item, $parents) {
+ $v = new View("organize_tree.html");
+ $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 = $parent->id == 1 || $v->selected ? "ui-icon-minus" : "ui-icon-plus";
- } else {
- $v->album_icon = "";
- }
-
- $v->children = "";
- foreach ($albums as $album) {
- $v->children .= $this->tree($item, $album);
- }
- return $v->__toString();
- }
-
- function startTask($operation, $id) {
- access::verify_csrf();
- $items = $this->input->post("item");
-
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
-
- $definition = $this->_getOperationDefinition($item, $operation);
-
- $task_def = Task_Definition::factory()
- ->callback("organize_task::run")
- ->description($definition["description"])
- ->name($definition["name"]);
- $task = task::create($task_def, array("items" => $items, "position" => 0, "target" => $id,
- "type" => $definition["type"],
- "batch" => ceil(count($items) * .1)));
- // @todo If there is only one item then call task_run($task->id); Maybe even change js so
- // we can call finish as well.
- batch::start();
- print json_encode(
- array("result" => "started",
- "runningMsg" => $definition["runningMsg"],
- "pauseMsg" => "<div class=\"gWarning\">{$definition['pauseMsg']}</div>",
- "resumeMsg" => "<div class=\"gWarning\">{$definition['resumeMsg']}</div>",
- "task" => array("id" => $task->id,
- "percent_complete" => $task->percent_complete,
- "type" => $task->get("type"),
- "status" => $task->status,
- "state" => $task->state,
- "done" => $task->done)));
- }
-
- 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);
+ $v->album_icon = empty($parents[$item->id]) ? "ui-icon-plus" : "ui-icon-minus";
- $form = organize::get_general_edit_form($item);
- if ($form->validate()) {
- $orig = clone $item;
- $item->title = $form->title->value;
- $item->description = $form->description->value;
- $item->rename($form->dirname->value);
- $item->save();
-
- if ($item->is_album()) {
- log::success("content", "Updated album", "<a href=\"albums/$item->id\">view</a>");
- $message = t("Saved album %album_title", array("album_title" => p::purify($item->title)));
- } else {
- log::success("content", "Updated photo", "<a href=\"photos/$item->id\">view</a>");
- $message = t("Saved photo %photo_title", array("photo_title" => p::purify($item->title)));
+ foreach ($albums as $album) {
+ $v->children[] = $this->_tree($album, $parents);
}
- 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", "<a href=\"albums/$item->id\">view</a>");
- $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");
}
+ return $v;
}
}
diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css
index e58cd5a5..a4b5fdbd 100644
--- a/modules/organize/css/organize.css
+++ b/modules/organize/css/organize.css
@@ -1,41 +1,61 @@
-/* @todo move to theme css */
/*******************************************************************
* Dialog wide stylings
*/
-#gMessage {
- margin-bottom: .4em;
+#gOrganizeDialog {
+ text-align: left;
}
-#gMessage .gInfo {
- background-color: transparent;
- background-image: none;
- padding-left: .4em;
+#gOrganize {
+ overflow: hidden;
}
-#gOrganizeProgressDialog {
- text-align: left;
+#gOrganize #bd {
+ height: 100%;
+}
+
+#gOrganize .yui-u {
+ width: 75%;
}
-#gDialog .yui-gf div.first {
- width: 20%;
+#gOrganize .yui-gf .first {
+ width: 25%;
}
-#gDialog .yui-gf .yui-u {
- width: 80%;
+#gOrganize .yui-gf #gMessage {
+ margin-bottom: .4em;
+ width: 75%;
+ white-space: nowrap;
+}
+
+#gOrganizeDetail {
+ height: 100%;
+}
+
+#gMessage .gInfo {
+ font-weight: bold;
+ padding-left: 2em;
}
/*******************************************************************
* Album Tree styling
*/
#gOrganizeTreeContainer {
- overflow-y: auto;
+ height: 100%;
+ overflow: auto;
margin: 0 !important;
padding: 0 !important;
}
-#gOrganizeAlbumDescription {
- height: 2em;
- overflow-y: auto;
+#gOrganizeTreeContainer ul ul li {
+ padding-left: 1.2em;
+}
+
+.gBranchText:hover {
+ border: 1px dashed #999;
+}
+
+.gBranchEmpty {
+ visibility: hidden;
}
.gBranchSelected {
@@ -45,37 +65,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,7 +87,6 @@
border: 1px solid #999 !important;
border-top: none !important;
border-left: none !important;
- margin-left: -1em !important;
overflow-x: hidden;
overflow-y: auto;
}
@@ -92,63 +95,41 @@
padding: .5em;
}
-.gMicroThumbContainer {
+.gMicroThumb {
display: block;
float: left;
- font-size: .7em;
+ font-size: .8em;
height: 9em;
margin-bottom: 1em;
margin-left: 1em;
- opacity: .4;
- padding: 0 .5em;
-}
-
-.gMicroThumb {
- height: 9em;
- width: 9em;
- background-color: #fff;
- display: block;
- float: left;
+ opacity: .5;
text-align: center;
+ width: 9em;
}
-#gMicroThumbPanel #gMicroThumbGrid .gAlbum {
- background-color: #e8e8e8;
-}
-
-#gMicroThumbPanel #gMicroThumbGrid :hover {
+.gMicroThumb.ui-selected {
opacity: 1;
}
-.gMicroThumbContainer.ui-selected {
- opacity: 1;
-}
-#gDragHelper .gMicroThumbGrid {
- background-color: transparent;
- padding: 0;
- overflow: visible;
+.gThumbnail {
+ padding: .5em;
}
-#gDragHelper .gMicroThumbContainer {
- display: block;
- margin: 0;
- padding: 0;
+#gMicroThumbPanel #gMicroThumbGrid .gAlbum {
+ background-color: #e8e8e8;
}
-#gDragHelper .gMicroThumb {
- background-color: transparent;
- height: auto;
- width: auto;
+#gMicroThumbPanel #gMicroThumbGrid :hover {
+ opacity: 1;
}
-
/****************************************************************
* Organize Edit Drawer styling
*/
#gOrganizeEditDrawer {
background-color: #13A;
- width: 90%;
+ width: 100% !important;
}
#gOrganizeEditDrawerPanel {
@@ -204,79 +185,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.php b/modules/organize/helpers/organize.php
deleted file mode 100644
index 25284771..00000000
--- a/modules/organize/helpers/organize.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 Bharat Mediratta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
- */
-class organize_Core {
- static function get_general_edit_form($item) {
- $generalPane = new Forge("organize/__FUNCTION__", "", "post",
- array("id" => "gEditGeneral", "ref" => "general"));
- // In this case we know there is only 1 item, but in general we should loop
- // and create multiple hidden items.
- $generalPane->hidden("item[]")->value($item->id);
- $generalPane->input("title")->label(t("Title"))->value($item->title);
- $generalPane->textarea("description")->label(t("Description"))->value($item->description);
- $generalPane->input("dirname")->label(t("Path Name"))->value($item->name)
- ->callback("item::validate_no_slashes")
- ->error_messages("no_slashes", t("The directory name can't contain a \"/\""))
- ->callback("item::validate_no_trailing_period")
- ->error_messages("no_trailing_period", t("The directory name can't end in \".\""))
- ->callback("item::validate_no_name_conflict")
- ->error_messages("conflict", t("The path name is not unique"));
-
- return $generalPane;
- }
-
- static function get_sort_edit_form($item) {
- $sortPane = new Forge("organize/__FUNCTION__", "", "post",
- array("id" => "gEditSort", "ref" => "sort"));
- $sortPane->hidden("item[]")->value($item->id);
- $sortPane->dropdown("column", array("id" => "gAlbumSortColumn"))
- ->label(t("Sort by"))
- ->options(array("weight" => t("Order Added"),
- "captured" => t("Capture Date"),
- "created" => t("Creation Date"),
- "title" => t("Title"),
- "updated" => t("Updated Date"),
- "view_count" => t("Number of views"),
- "rand_key" => t("Random")))
- ->selected($item->sort_column);
- $sortPane->dropdown("direction", array("id" => "gAlbumSortDirection"))
- ->label(t("Order"))
- ->options(array("ASC" => t("Ascending"),
- "DESC" => t("Descending")))
- ->selected($item->sort_order);
-
- return $sortPane;
- }
-
- static function get_tag_form($itemids) {
- $tagPane = new Forge("organize/__FUNCTION__", "", "post",
- array("id" => "gEditTags", "ref" => "edit_tags"));
- $tagPane->hidden("item")->value(implode("|", $itemids));
- $item_count = count($itemids);
- $ids = implode(", ", $itemids);
-
- // Lame stopgap security check. This code is going to get rewritten anyway.
- foreach ($itemids as $id) {
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
- }
-
- $tags = Database::instance()->query(
- "SELECT t.name, COUNT(it.item_id) as count
- FROM {items_tags} it, {tags} t
- WHERE it.tag_id = t.id
- AND it.item_id in($ids)
- GROUP BY it.tag_id
- ORDER BY t.name ASC");
- $taglist = array();
- foreach ($tags as $tag) {
- $taglist[] = $tag->name . ($item_count > $tag->count ? "*" : "");
- }
- $taglist = implode("; ", $taglist);
- $tagPane->textarea("tags")->label(t("Tags"))->value($taglist);
-
- return $tagPane;
- }
-
-} \ No newline at end of file
diff --git a/modules/organize/helpers/organize_event.php b/modules/organize/helpers/organize_event.php
index 99a28673..7d6b3e24 100644
--- a/modules/organize/helpers/organize_event.php
+++ b/modules/organize/helpers/organize_event.php
@@ -23,11 +23,11 @@ class organize_event_Core {
if ($item && access::can("edit", $item) && $item->is_album()) {
$menu->get("options_menu")
- ->append(Menu::factory("link")
+ ->append(Menu::factory("dialog")
->id("organize")
->label(t("Organize Album"))
->css_id("gOrganizeLink")
- ->url(url::site("organize/index/{$item->id}")));
+ ->url(url::site("organize/dialog/{$item->id}")));
}
}
}
diff --git a/modules/organize/helpers/organize_task.php b/modules/organize/helpers/organize_task.php
deleted file mode 100644
index dc474818..00000000
--- a/modules/organize/helpers/organize_task.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 Bharat Mediratta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
- */
-class organize_task_Core {
- static function available_tasks() {
- // Return empty array so nothing appears in the maintenance screen
- return array();
- }
-
- static function run($task) {
- $context = unserialize($task->context);
- $taskType = $context["type"];
-
- try {
- $target = ORM::factory("item", $context["target"]);
- $total = count($context["items"]);
- $stop = min($total - $context["position"], $context["batch"]);
- $context["post_process"] = array();
- for ($offset = 0; $offset < $stop; $offset++) {
- $current_id = $context["position"] + $offset;
- $id = $context["items"][$current_id];
- switch ($taskType) {
- case "move":
- $source = ORM::factory("item", $id);
- access::required("view", $source);
- access::required("view", $target);
- access::required("edit", $source);
- access::required("edit", $target);
-
- item::move($source, $target);
- break;
-
- case "rearrange":
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
-
- Database::instance()
- ->query("Update {items} set weight = {$context["position"]} where id=$id;");
- break;
-
- case "rotateCcw":
- case "rotateCw":
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
-
- if ($item->is_photo()) {
- $context["post_process"]["reload"][] =
- self::_do_rotation($item, $taskType == "rotateCcw" ? -90 : 90);
- }
- break;
-
- case "albumCover":
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("view", $item->parent());
- access::required("edit", $item->parent());
-
- item::make_album_cover($item);
- break;
-
- case "delete":
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
-
- $item->delete();
- $context["post_process"]["remove"][] = array("id" => $id);
- break;
-
- default:
- throw new Exception("Task '$taskType' is not implemented");
- }
- }
- $context["position"] += $stop;
- $task->state = "success";
- } catch(Exception $e) {
- $task->status = $e->getMessage();
- $task->state = "error";
- $task->save();
- throw $e;
- }
- $task->context = serialize($context);
- $total = count($context["items"]);
- $task->percent_complete = $context["position"] / (float)$total * 100;
- $task->done = $context["position"] == $total || $task->state == "error";
- }
-
- private static function _do_rotation($item, $degrees) {
- // This code is copied from Quick_Controller::rotate
- graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees));
-
- list($item->width, $item->height) = getimagesize($item->file_path());
- $item->resize_dirty= 1;
- $item->thumb_dirty= 1;
- $item->save();
-
- graphics::generate($item);
-
- $parent = $item->parent();
- if ($parent->album_cover_item_id == $item->id) {
- copy($item->thumb_path(), $parent->thumb_path());
- $parent->thumb_width = $item->thumb_width;
- $parent->thumb_height = $item->thumb_height;
- $parent->save();
- }
- list ($height, $width) = $item->scale_dimensions(90);
- $margin_top = (90 - $height) / 20;
-
- return array("src" => $item->thumb_url() . "?rnd=" . rand(),
- "id" => $item->id,
- "marginTop" => "{$margin_top}em", "width" => $width, "height" => $height);
- }
-} \ No newline at end of file
diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php
deleted file mode 100644
index e4feba2b..00000000
--- a/modules/organize/helpers/organize_theme.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 Bharat Mediratta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
- */
-class organize_theme {
- static function head($theme) {
- // @tdo remove the addition css and organize.js (just here to test)
- $theme->script("organize_init.js");
- $theme->script("organize.js");
- $theme->css("organize.css");
- }
-}
diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js
index 31657d3a..05693200 100644
--- a/modules/organize/js/organize.js
+++ b/modules/organize/js/organize.js
@@ -1,621 +1,55 @@
-/*
- * @todo Trap resize of dialog and resize the child areas (tree, grid and edit form)
- */
-var url;
-var paused = false;
-var task = null;
-var transitItems = [];
-var heightMicroThumbPanel;
-
-// **************************************************************************
-// JQuery UI Widgets
-// Draggable
-var draggable = {
- handle: ".gMicroThumbContainer.ui-selected",
- revert: true,
- zindex: 2000,
- distance: 10,
- helper: function(event, ui) {
- if (!$(event.currentTarget).hasClass("ui-selected")) {
- $(event.currentTarget).addClass("ui-selected");
- setDrawerButtonState();
- }
- $("#gMicroThumbPanel").append("<div id=\"gDragHelper\"><ul></ul></div>");
- var beginTop = event.pageY;
- var beginLeft = event.pageX;
- var zindex = $(".gMicroThumbContainer").draggable("option", "zindex");
- $("#gDragHelper").css('top', event.pageY - 22.5);
- $("#gDragHelper").css('left', event.pageX + 22.5);
- var placeHolder = $(this).clone();
- $(placeHolder).attr("id", "gPlaceHolder");
- $(placeHolder).css("visibility", "hidden");
- $(placeHolder).removeClass("ui-selected");
- $(placeHolder).removeClass("ui-draggable");
- $(this).after(placeHolder);
-
- $("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());
- }
+(function($) {
+ $.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", 68);
+ $("#gDialog").dialog("option", "zIndex", 70);
+ $("#gDialog").bind("dialogopen", function(event, ui) {
+ $("#gOrganize").height($("#gDialog").innerHeight() - 20);
+ $("#gMicroThumbPanel").height($("#gDialog").innerHeight() - 90);
});
- break;
- case "select-all":
- $("#gMicroThumbGrid li").addClass("ui-selected");
- $("#gMicroThumbSelectAll").hide();
- $("#gMicroThumbUnselectAll").show();
- setDrawerButtonState();
- getEditForm();
- break;
- case "unselect-all":
- $("#gMicroThumbGrid li").removeClass("ui-selected");
- $("#gMicroThumbSelectAll").show();
- $("#gMicroThumbUnselectAll").hide();
- setDrawerButtonState();
- break;
- case "done":
- $("#gDialog").dialog("close");
- break;
- case "submit":
- var currentTab = $("#gOrganizeEditForm").tabs("option", "selected");
- var form = $("#pane-"+currentTab+" form");
- var url = $(form).attr("action")
- .replace("__FUNCTION__", $(form).attr("ref"));
- $.ajax({
- data: $(form).serialize(),
- dataType: "json",
- success: function (data, textStatus) {
- $("#pane-"+currentTab).children("form").replaceWith(data.form);
- if (data.message) {
- $("#gMessage").empty().append("<div class='gSuccess'>" + data.message + "</div>");
- }
- },
- type: "POST",
- url: url
+
+ $("#gDialog").bind("dialogclose", function(event, ui) {
+ window.location.reload();
});
- 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"))
+
+ $("#gDialog #gMicroThumbDone").click(function(event) {
+ $("#gDialog").dialog("close");
});
- break;
- case "delete":
- if (!confirm(CONFIRM_DELETE)) {
- break;
+
+ $(".gBranchText span").click($.organize.collapse_or_expand_tree);
+ $(".gBranchText").click($.organize.show_album);
+
+ $("#gMicroThumbGrid").selectable({filter: ".gMicroThumb"});
+ },
+
+ /**
+ * Open or close a branch.
+ */
+ collapse_or_expand_tree: function(event) {
+ event.stopPropagation();
+ $(event.currentTarget).toggleClass("ui-icon-minus").toggleClass("ui-icon-plus");
+ $("#gOrganizeChildren-" + $(event.currentTarget).attr("ref")).toggle();
+ },
+
+ /**
+ * When the text of a selection is clicked, then show that albums contents
+ */
+ show_album: function(event) {
+ event.preventDefault();
+ if ($(event.currentTarget).hasClass("gBranchSelected")) {
+ return;
}
- 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})
+ 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);
});
- 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("<div class='gSuccess'>" + data.task.status + "</div>");
- },
- dataType: "json",
- type: "POST",
- url: get_organize_url("organize/finishTask", {task_id: task.id})
- });
- }
- $(".gMicroThumbContainer").draggable("enable");
-};
-
-// **************************************************************************
-
-/**
- * Dynamically initialize the organize dialog when it is displayed
- */
-function organize_dialog_init() {
- var size = getViewportSize();
- heightMicroThumbPanel = size.height() - 100;
- var width = size.width() - 100;
-
- // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475
- $(".sf-menu li.sfHover ul").css("z-index", 70);
-
- $("#gDialog").dialog("option", "width", width);
- $("#gDialog").dialog("option", "height", heightMicroThumbPanel);
-
- $("#gDialog").dialog("open");
- if ($("#gDialog h1").length) {
- $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html());
- } else if ($("#gDialog fieldset legend").length) {
- $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html());
- }
-
- $("#gDialog").bind("organize_close", function(target) {
- document.location.reload();
- });
-
- heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-top"));
- heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-bottom"));
- heightMicroThumbPanel -= $("#gMicroThumbPanel").position().top;
- heightMicroThumbPanel -= $("#gDialog #ft").height();
- heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").height();
- heightMicroThumbPanel = Math.round(heightMicroThumbPanel);
-
- $("#gMicroThumbPanel").height(heightMicroThumbPanel);
- $("#gOrganizeTreeContainer").height(heightMicroThumbPanel);
-
- $(".gOrganizeBranch .ui-icon").click(organizeToggleChildren);
- $(".gBranchText").droppable(treeDroppable);
- $(".gBranchText").click(organizeOpenFolder);
- retrieveMicroThumbs(item_id);
- //$.gallery_show_loading("#gDialog");
-
- $("#gMicroThumbPanel").droppable(thumbDroppable);
- $("#gMicroThumbPanel").selectable(selectable);
- $("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick);
-}
-
-function retrieveMicroThumbs() {
- var offset = $("#gMicroThumbGrid li").length;
- if (url == null) {
- var grid_width = $("#gMicroThumbPanel").width();
- url = $("#gMicroThumbPanel").attr("ref");
- url = url.replace("__WIDTH__", grid_width);
- url = url.replace("__HEIGHT__", heightMicroThumbPanel);
- }
- var url_data = url.replace("__OFFSET__", offset);
- url_data = url_data.replace("__ITEM_ID__", item_id);
- $.getJSON(url_data, getMicroThumbsCallback);
-}
-
-function organizeToggleChildren(event) {
- var id = $(this).attr("ref");
- var span_children = $("#gOrganizeChildren-" + id);
- if ($(this).hasClass("ui-icon-plus")) {
- $(this).removeClass("ui-icon-plus");
- $(this).addClass("ui-icon-minus");
- $("#gOrganizeChildren-" + id).removeClass("gBranchCollapsed");
- } else {
- $(this).removeClass("ui-icon-minus");
- $(this).addClass("ui-icon-plus");
- $("#gOrganizeChildren-" + id).addClass("gBranchCollapsed");
- }
- event.preventDefault();
-}
-
-function organizeOpenFolder(event) {
- var selected = $(".gBranchSelected");
- if ($(selected).attr("id") != $(this).attr("id")) {
- $(selected).removeClass("gBranchSelected");
- $(this).addClass("gBranchSelected");
- item_id = $(this).attr("ref");
- $("#gMicroThumbGrid").empty();
- retrieveMicroThumbs();
- }
- event.preventDefault();
-}
-
-function get_organize_url(uri, parms) {
- var url = rearrangeUrl;
- url = url.replace("__URI__", uri);
- url = url.replace("__ITEM_ID__", !parms.item_id ? "" : parms.item_id);
- url += (parms.item_id && parms.task_id) ? "/" : "";
- url = url.replace("__TASK_ID__", !parms.task_id ? "" : parms.task_id);
- return url;
-}
-
-/**
- * Set the enabled/disabled state of the buttons. The album cover is only enabled if
- * there is only 1 image selected
- */
-function setDrawerButtonState() {
- $("#gOrganizeFormThumbStack").empty();
- $("#gOrganizeEditForm").empty();
- var selectedCount = $("#gMicroThumbGrid li.ui-selected").length;
- if (selectedCount) {
- $("#gOrganizeEditHandleButtonsLeft a").removeAttr("disabled");
- $("#gOrganizeEditHandleButtonsLeft a").removeClass("ui-state-disabled");
-
- if (selectedCount > 1) {
- $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").attr("disabled", true);
- $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").addClass("ui-state-disabled");
- }
- setSelectedThumbs();
- } else {
- if ($("#gOrganizeEditDrawerPanel::visible").length) {
- $("#gOrganizeEditHandleButtonsLeft a[ref='close']").trigger("click");
- }
- $("#gOrganizeEditHandleButtonsLeft a").attr("disabled", true);
- $("#gOrganizeEditHandleButtonsLeft a").addClass("ui-state-disabled");
- }
-}
-
-function setSelectedThumbs() {
- if (!$("#gOrganizeEditDrawerPanel::visible").length) {
- return;
- }
- var position = $("#gOrganizeFormThumbStack").position();
- var beginLeft = position.left;
- var beginTop = 50;
- var zindex = 2000;
- $("li.ui-selected").each(function(i) {
- var clone = $(this).clone();
- $(clone).attr("id", "edit_clone_" + $(this).attr("ref"));
- $("#gOrganizeFormThumbStack").append(clone);
- $(clone).removeClass("ui-draggable");
- $(clone).removeClass("ui-selected");
- $(clone).css("margin-top", beginTop);
- $(clone).css("left", beginLeft);
- $(clone).css("z-index", zindex--);
-
- 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();
- }
-}
-
-function serializeItemIds(selector) {
- var postData = "";
- $(selector).each(function(i) {
- postData += "&item[]=" + $(this).attr("ref");
- });
-
- return postData;
-}
-
-function submitCurrentForm(event) {
- console.log("submitCurrentForm");
- return false;
-}
-
-function resetCurrentForm(event) {
- console.log("resetCurrentForm");
- return false;
-}
-
-function createProgressDialog(title) {
- $("body").append("<div id='gOrganizeProgressDialog'>" +
- "<div class='gProgressBar'></div>" +
- "<button id='gOrganizeTaskPause' class='ui-state-default ui-corner-all'>" + PAUSE_BUTTON + "</button>" +
- "<button id='gOrganizeTaskResume' class='ui-state-default ui-corner-all' style='display: none'>" + RESUME_BUTTON + "</button>" +
- "<button id='gOrganizeTaskCancel' class='ui-state-default ui-corner-all' style='display: none'>" + CANCEL_BUTTON + "</button>" +
- "</div>");
- $("#gOrganizeProgressDialog").dialog({
- autoOpen: true,
- autoResize: false,
- modal: true,
- resizable: false,
- title: title
- });
-
- $(".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("<div class='gWarning'>" + data.task.status + "</div>");
- $("#gOrganizeProgressDialog").dialog("destroy").remove();
- },
- dataType: "json",
- type: "POST",
- url: get_organize_url("organize/cancelTask", {task_id: task.id})
- });
- });
-}
-
-// **************************************************************************
-// Functions that should probably be in a gallery namespace
-function getViewportSize() {
- return {
- width : function() {
- return window.innerWidth
- || document.documentElement && document.documentElement.clientWidth
- || document.body.clientWidth;
- },
- height : function() {
- return window.innerHeight
- || document.documentElement && document.documentElement.clientHeight
- || document.body.clientHeight;
- }
};
-}
-
-function displayAjaxError(error) {
- $("body").append("<div id=\"gAjaxError\" title=\"" + FATAL_ERROR + "\">" + error + "</div>");
-
- $("#gAjaxError").dialog({
- autoOpen: true,
- autoResize: false,
- modal: true,
- resizable: true,
- width: 610,
- height: $("#gDialog").height()
- });
-}
+})(jQuery);
diff --git a/modules/organize/js/organize_init.js b/modules/organize/js/organize_init.js
deleted file mode 100644
index 30bc78dd..00000000
--- a/modules/organize/js/organize_init.js
+++ /dev/null
@@ -1,29 +0,0 @@
-$("document").ready(function() {
- $("#gOrganizeLink").click(function(event) {
- event.preventDefault();
- var href = event.target.href;
-
- $("body").append('<div id="gDialog"></div>');
-
- $("#gDialog").dialog({
- autoOpen: false,
- autoResize: false,
- modal: true,
- resizable: false,
- close: function () {
- $("#gDialog").trigger("organize_close");
- $("#gDialog").dialog("destroy").remove();
- },
- zIndex: 75
- });
-
- //$.gallery_show_loading("#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 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<!-- ?= html::script("modules/organize/js/organize.js") ? -->
-<script>
- var FATAL_ERROR = "<?= t("Fatal Error") ?>";
- var PAUSE_BUTTON = "<?= t("Pause") ?>";
- var RESUME_BUTTON = "<?= t("Resume") ?>";
- var CANCEL_BUTTON = "<?= t("Cancel") ?>";
- var INVALID_DROP_TARGET = "<div class=\"gError\"><?= t("Drop cancelled as it would result in a recursive move") ?></div>";
-var CONFIRM_DELETE = "<?= t("Do you really want to delete the selected albums and/or photos") ?>"
- var item_id = <?= $item->id ?>;
-
- var csrf = "<?= $csrf ?>";
- var rearrangeUrl = "<?= url::site("__URI__/__ITEM_ID____TASK_ID__?csrf=$csrf") ?>";
- $("#doc3").ready(function() {
- organize_dialog_init();
- });
-</script>
-<fieldset style="display: none">
- <legend><?= t("Organize %name", array("name" => p::purify($item->title))) ?></legend>
-</fieldset>
-<div id="doc3" class="yui-t7">
- <div id="bd">
- <div class="yui-gf">
- <div class="yui-u first">
- <h3><?= t("Albums") ?></h3>
- </div>
- <div id="gMessage" class="yui-u">
- <div class="gInfo"><?= t("Select one or more items to edit; drag and drop items to re-order or move between albums") ?></div>
- </div>
- </div>
- <div class="yui-gf">
- <div id="gOrganizeTreeContainer" class="yui-u first">
- <?= $album_tree ?>
- </div>
- <div id="gMicroThumbPanel" class="yui-u"
- ref="<?= url::site("organize/content/__ITEM_ID__?width=__WIDTH__&amp;height=__HEIGHT__&amp;offset=__OFFSET__") ?>">
- <ul id="gMicroThumbGrid"></ul>
- </div>
- <div id="gOrganizeEditDrawer" class="yui-u">
- <div id="gOrganizeEditDrawerPanel" class="yui-gf">
- <div id="gOrganizeFormThumbs" class="yui-u first">
- <ul id="gOrganizeFormThumbStack" />
- </div>
- <div id="gOrganizeEditForm">
- </div>
- </div>
- <div id="gOrganizeEditDrawerHandle">
- <?= $button_pane ?>
- </div>
- </div>
- </div>
- </div>
-</div>
diff --git a/modules/organize/views/organize_album.html.php b/modules/organize/views/organize_album.html.php
deleted file mode 100644
index ae2d5d51..00000000
--- a/modules/organize/views/organize_album.html.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<ul>
- <li class="gOrganizeBranch ui-icon-left" ref="<?= $album->id ?>">
- <span id="gOrganizeIcon-<?= $album->id ?>" ref="<?= $album->id ?>"
- class="ui-icon <?= $album_icon ?> <?= $album_icon ? "" : "gBranchEmpty" ?>">
- </span>
-
- <div id="gOrganizeBranch-<?= $album->id ?>" ref="<?= $album->id ?>"
- class="<?= $selected ? "gBranchSelected" : "" ?> gBranchText">
- <?= p::clean($album->title) ?>
- </div>
- <div id="gOrganizeChildren-<?= $album->id ?>"
- class="<?= $album_icon == "ui-icon-plus" ? "gBranchCollapsed" : "" ?>">
- <?= $children ?>
- <div>
- </li>
-</ul>
diff --git a/modules/organize/views/organize_button_pane.html.php b/modules/organize/views/organize_button_pane.html.php
deleted file mode 100644
index c5839a44..00000000
--- a/modules/organize/views/organize_button_pane.html.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="gOrganizeEditHandleButtonsLeft">
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="edit"
- disabled="1" title="<?= t("Open Drawer") ?>">
- <span class="ui-icon ui-icon-arrowthickstop-1-n"><?= t("Open Drawer") ?></span>
- </a>
-
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="close"
- disabled="1" title="<?= t("Close Drawer") ?>" style="display: none">
- <span class="ui-icon ui-icon-arrowthickstop-1-s"><?= t("Close Drawer") ?></span>
- </a>
-
- <? if (graphics::can("rotate")): ?>
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="rotateCcw"
- disabled="1" title="<?= t("Rotate 90 degrees counter clockwise") ?>">
- <span class="ui-icon ui-icon-rotate-ccw"><?= t("Rotate 90 degrees counter clockwise") ?></span>
- </a>
-
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="rotateCw"
- disabled="1" title="<?= t("Rotate 90 degrees clockwise") ?>">
- <span class="ui-icon ui-icon-rotate-cw"> <?= t("Rotate 90 degrees clockwise") ?></span>
- </a>
- <? endif ?>
-
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="albumCover"
- disabled="1" title="<?= t("Choose this photo as the album cover") ?>">
- <span class="ui-icon ui-icon-star"><?= t("Choose this photo as the album cover") ?></span>
- </a>
-
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="delete"
- disabled="1" title="<?= t("Delete selection") ?>">
- <span class="ui-icon ui-icon-trash"><?= t("Delete selection") ?></span>
- </a>
-</div>
-<div id="gOrganizeEditHandleButtonsMiddle">
- <a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="submit"
- title="<?= t("Apply Changes") ?>" style="display: none" >
- <span class="ui-icon ui-icon-check"><?= t("Apply Changes") ?></span>
- </a>
-
- <a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="reset"
- title="<?= t("Reset Form") ?>" style="display: none" >
- <span class="ui-icon ui-icon-closethick"><?= t("Reset Form") ?></span>
- </a>
-</div>
-<div id="gOrganizeEditHandleButtonsRight">
- <a id="gMicroThumbSelectAll" href="#" ref="select-all" class="gButtonLink ui-corner-all ui-state-default"><?= t("Select all") ?></a>
- <a id="gMicroThumbUnselectAll" href="#" ref="unselect-all" style="display: none" class="gButtonLink ui-corner-all ui-state-default"><?= t("Deselect all") ?></a>
- <a id="gMicroThumbDone" href="#" ref="done" class="gButtonLink ui-corner-all ui-state-default"><?= t("Close") ?></a>
-</div>
diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php
new file mode 100644
index 00000000..b946d82b
--- /dev/null
+++ b/modules/organize/views/organize_dialog.html.php
@@ -0,0 +1,45 @@
+<?php defined("SYSPATH") or die("No direct script access.") ?>
+<link rel="stylesheet" type="text/css" href="<?= url::file("modules/organize/css/organize.css") ?>" />
+<div id="gOrganize" class="gDialogPanel">
+ <h1 style="display:none"><?= t("Organize %name", array("name" => p::purify($title))) ?></h1>
+ <div id="bd">
+ <div class="yui-gf">
+ <div class="yui-u first">
+ <h3><?= t("Albums") ?></h3>
+ </div>
+ <div id="gMessage" class="yui-u">
+ <div class="gInfo"><?= t("Select one or more items to edit; drag and drop items to re-order or move between albums") ?></div>
+ </div>
+ </div>
+ <div class="yui-gf">
+ <div id="gOrganizeTreeContainer" class="yui-u first">
+ <ul id="gOrganizeAlbumTree">
+ <?= $album_tree ?>
+ </ul>
+ </div>
+ <div id="gOrganizeDetail" class="yui-u">
+ <div id="gMicroThumbPanel"
+ ref="<?= url::site("organize/content/__ITEM_ID__/__OFFSET__") ?>">
+ <ul id="gMicroThumbGrid">
+ <?= $micro_thumb_grid ?>
+ </ul>
+ </div>
+ <div id="gOrganizeEditDrawer" class="yui-u">
+ <div id="gOrganizeEditDrawerPanel" class="yui-gf">
+ </div>
+ <div id="gOrganizeEditDrawerHandle">
+ <div id="gOrganizeEditHandleButtonsRight">
+ <a id="gMicroThumbDone" href="#" ref="done"
+ class="gButtonLink ui-corner-all ui-state-default"><?= t("Close") ?></a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<script type="text/javascript" src="<?= url::file("modules/organize/js/organize.js") ?>"></script>
+<script type="text/javascript">
+ $("#gOrganize").ready($.organize.init);
+</script>
diff --git a/modules/organize/views/organize_edit.html.php b/modules/organize/views/organize_edit.html.php
deleted file mode 100644
index 1adf290f..00000000
--- a/modules/organize/views/organize_edit.html.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<ul>
-<? foreach ($panes as $idx => $pane): ?>
- <li><a href="#pane-<?= $idx ?>"><?= $pane["label"] ?></a></li>
-<? endforeach?>
-</ul>
-
-<? if (count($panes) > 0): ?>
- <? foreach ($panes as $idx => $pane): ?>
- <div id="pane-<?= $idx ?>" class="gOrganizeEditPane ui-tabs-hide"><?= $pane["content"] ?></div>
- <? endforeach?>
-<? else: ?>
-<div class="gWarning"><?= t("No Edit pages apply to the selected items") ?></div>
-<? endif ?> \ No newline at end of file
diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php
index c80696ad..0d54c5c8 100644
--- a/modules/organize/views/organize_thumb_grid.html.php
+++ b/modules/organize/views/organize_thumb_grid.html.php
@@ -1,12 +1,20 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<? foreach ($children as $i => $child): ?>
-<? $item_class = "gPhoto"; ?>
-<? if ($child->is_album()): ?>
- <? $item_class = "gAlbum"; ?>
-<? endif ?>
-<li id="thumb_<?= $child->id ?>" class="gMicroThumbContainer" ref="<?= $child->id ?>">
- <div id="gMicroThumb-<?= $child->id ?>" class="gMicroThumb <?= $item_class ?>">
- <?= $child->thumb_img(array("class" => "gThumbnail"), $thumbsize, true) ?>
- </div>
+<? foreach ($item->children(25, $offset) as $child): ?>
+<li id="gMicroThumb_<?= $child->id ?>"
+ class="gMicroThumb <?= $child->is_album() ? "gAlbum" : "gPhoto" ?>"
+ ref="<?= $child->id ?>">
+ <?= $child->thumb_img(array("class" => "gThumbnail"), 90, true) ?>
</li>
<? endforeach ?>
+
+<? if ($item->children_count() > $offset): ?>
+<script>
+ setTimeout(function() {
+ $.get("<?= url::site("organize/content/$item->id/" . ($offset + 25)) ?>",
+ function(data) {
+ $("#gMicroThumbGrid").append(data);
+ }
+ );
+ }, 50);
+</script>
+<? endif ?>
diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php
index d2cdd957..99b0dc1a 100644
--- a/modules/organize/views/organize_tree.html.php
+++ b/modules/organize/views/organize_tree.html.php
@@ -1,4 +1,17 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<? foreach ($children as $i => $child): ?>
-<? endforeach ?>
-
+<li class="gOrganizeBranch ui-icon-left" ref="<?= $album->id ?>">
+ <div id="gOrganizeBranch-<?= $album->id ?>" ref="<?= $album->id ?>"
+ class="<?= $selected ? "gBranchSelected" : "" ?> gBranchText">
+ <span id="gOrganizeIcon-<?= $album->id ?>" ref="<?= $album->id ?>"
+ class="ui-icon <?= $album_icon ?>">
+ </span>
+ <?= p::clean($album->title) ?>
+ </div>
+ <ul id="gOrganizeChildren-<?= $album->id ?>"
+ class="<?= $album_icon == "ui-icon-plus" ? "gBranchCollapsed" : "" ?>">
+ <li style="display:none">&nbsp;</li>
+ <? foreach ($children as $child): ?>
+ <?= $child ?>
+ <? endforeach ?>
+ </ul>
+</li>