diff options
Diffstat (limited to 'modules/organize')
| -rw-r--r-- | modules/organize/controllers/organize.php | 558 | ||||
| -rw-r--r-- | modules/organize/css/organize.css | 268 | ||||
| -rw-r--r-- | modules/organize/helpers/organize.php | 94 | ||||
| -rw-r--r-- | modules/organize/helpers/organize_event.php | 4 | ||||
| -rw-r--r-- | modules/organize/helpers/organize_task.php | 131 | ||||
| -rw-r--r-- | modules/organize/helpers/organize_theme.php | 13 | ||||
| -rw-r--r-- | modules/organize/js/organize.js | 779 | ||||
| -rw-r--r-- | modules/organize/js/organize_init.js | 29 | ||||
| -rw-r--r-- | modules/organize/views/organize.html.php | 53 | ||||
| -rw-r--r-- | modules/organize/views/organize_album.html.php | 17 | ||||
| -rw-r--r-- | modules/organize/views/organize_button_pane.html.php | 50 | ||||
| -rw-r--r-- | modules/organize/views/organize_dialog.html.php | 47 | ||||
| -rw-r--r-- | modules/organize/views/organize_edit.html.php | 14 | ||||
| -rw-r--r-- | modules/organize/views/organize_thumb_grid.html.php | 26 | ||||
| -rw-r--r-- | modules/organize/views/organize_tree.html.php | 44 | 
15 files changed, 451 insertions, 1676 deletions
| diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index d60aa838..2b966657 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -18,523 +18,131 @@   * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.   */  class Organize_Controller extends Controller { -  private static $_MICRO_THUMB_SIZE = 90; -  private static $_MICRO_THUMB_PADDING = 5; +  function dialog($album_id) { +    $album = ORM::factory("item", $album_id); +    access::required("view", $album); +    access::required("edit", $album); -  function index($item_id=1) { -    $item = ORM::factory("item", $item_id); -    $root = ($item->id == 1) ? $item : ORM::factory("item", 1); -    access::required("view", $item); -    access::required("edit", $item); - -    $v = new View("organize.html"); -    $v->root = $root; -    $v->item = $item; -    $v->album_tree = $this->tree($item, $root); -    $v->button_pane = new View("organize_button_pane.html"); +    $v = new View("organize_dialog.html"); +    $v->album = $album; +    $v->album_tree = self::_tree($album); +    $v->micro_thumb_grid = self::_get_micro_thumb_grid($album, 0);      print $v;    } -  function content($item_id) { -    $item = ORM::factory("item", $item_id); -    access::required("view", $item); -    access::required("edit", $item); - -    $width = $this->input->get("width"); -    $height = $this->input->get("height"); -    $offset = $this->input->get("offset", 0); -    $thumbsize = self::$_MICRO_THUMB_SIZE + 2 * self::$_MICRO_THUMB_PADDING; -    $page_size = ceil($width / $thumbsize) * ceil($height / $thumbsize); - -    $v = new View("organize_thumb_grid.html"); -    $v->children = $item->children($page_size, $offset); -    $v->thumbsize = self::$_MICRO_THUMB_SIZE; -    $v->padding = self::$_MICRO_THUMB_PADDING; -    $v->offset = $offset; - -    print json_encode(array("count" => $v->children->count(), -                            "data" => $v->__toString())); -  } - -  function header($item_id) { -    $item = ORM::factory("item", $item_id); -    access::required("view", $item); -    access::required("edit", $item); +  function album($album_id, $offset) { +    $album = ORM::factory("item", $album_id); +    access::required("view", $album); +    access::required("edit", $album);      print json_encode( -      array("title" => SafeString::purify($item->title), -            "description" => empty($item->description) ? "" : SafeString::purify($item->description))); +      array("grid" => self::_get_micro_thumb_grid($album, $offset)->__toString(), +            "sort_column" => $album->sort_column, +            "sort_order" => $album->sort_order));    } -  function tree($item, $parent) { -    access::required("view", $item); -    access::required("edit", $item); - -    $albums = ORM::factory("item") -      ->where(array("parent_id" => $parent->id, "type" => "album")) -      ->orderby(array("title" => "ASC")) -      ->find_all(); - -    $v = new View("organize_album.html"); -    $v->album = $parent; -    $v->selected = $parent->id == $item->id; - -    if ($albums->count()) { -      $v->album_icon = $parent->id == 1 || $v->selected ? "ui-icon-minus" : "ui-icon-plus"; -    } else { -      $v->album_icon = ""; -    } - -    $v->children = ""; -    foreach ($albums as $album) { -      $v->children .= $this->tree($item, $album); -    } -    return $v->__toString(); -  } - -  function startTask($operation, $id) { +  function move_to($album_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); +    $album = ORM::factory("item", $album_id); +    foreach ($this->input->post("source_ids") as $source_id) { +      item::move(ORM::factory("item", $source_id), $album); +    } -    $task_def = Task_Definition::factory() -      ->callback("organize_task::run") -      ->description($definition["description"]) -      ->name($definition["name"]); -    $task = task::create($task_def, array("items" => $items, "position" => 0, "target" => $id, -                                          "type" => $definition["type"], -                                          "batch" => ceil(count($items) * .1))); -    // @todo If there is only one item then call task_run($task->id); Maybe even change js so -    // we can call finish as well. -    batch::start();      print json_encode( -      array("result" => "started", -            "runningMsg" => $definition["runningMsg"], -            "pauseMsg" => "<div class=\"gWarning\">{$definition['pauseMsg']}</div>", -            "resumeMsg" => "<div class=\"gWarning\">{$definition['resumeMsg']}</div>", -            "task" => array("id" => $task->id, -                            "percent_complete" => $task->percent_complete, -                            "type" => $task->get("type"), -                            "status" => $task->status, -                            "state" => $task->state, -                            "done" => $task->done))); +      array("tree" => self::_tree($album)->__toString(), +            "grid" => self::_get_micro_thumb_grid($album, 0)->__toString()));    } -  function runTask($task_id) { +  function rearrange($target_id, $before_or_after) {      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(); +    $target = ORM::factory("item", $target_id); +    $album = $target->parent(); +    access::required("view", $album); +    access::required("edit", $album); -    $task = ORM::factory("task", $task_id); -    if (!$task->loaded || $task->owner_id != user::active()->id) { -      access::forbidden(); -    } +    $source_ids = $this->input->post("source_ids", array()); -    if ($task->done) { -      $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; +    if ($album->sort_column != "weight") { +      $i = 0; +      foreach ($album->children() as $child) { +        // Do this directly in the database to avoid sending notifications +        Database::Instance()->update("items", array("weight" => ++$i), array("id" => $child->id));        } -      $task->save(); -   } - -    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(); +      $album->sort_column = "weight"; +      $album->sort_order = "ASC"; +      $album->save(); +      $target->reload();      } -    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(); +    // Find the insertion point +    $target_weight = $target->weight; +    if ($before_or_after == "after") { +      $target_weight++;      } -    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); +    // Make a hole +    $count = count($source_ids); +    Database::Instance()->query( +      "UPDATE {items} " . +      "SET `weight` = `weight` + $count " . +      "WHERE `weight` >= $target_weight AND `parent_id` = {$album->id}"); -      $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)); -      } +    // Insert source items into the hole +    foreach ($source_ids as $source_id) { +      Database::Instance()->update( +        "items", array("weight" => $target_weight++), array("id" => $source_id));      } -    $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(); +    module::event("album_rearrange", $album); -    $itemids = $this->input->post("item"); -    $item = ORM::factory("item") -      ->in("id", $itemids[0]) -      ->find(); -    access::required("view", $item); -    access::required("edit", $item); - -    $form = organize::get_general_edit_form($item); -    if ($form->validate()) { -      $orig = clone $item; -      $item->title = $form->title->value; -      $item->description = $form->description->value; -      $item->rename($form->dirname->value); -      $item->save(); - -      if ($item->is_album()) { -        log::success("content", "Updated album", "<a href=\"albums/$item->id\">view</a>"); -        $message = t("Saved album %album_title", array("album_title" => SafeString::purify($item->title))); -      } else { -        log::success("content", "Updated photo", "<a href=\"photos/$item->id\">view</a>"); -        $message = t("Saved photo %photo_title", array("photo_title" => SafeString::purify($item->title))); -      } -      print json_encode(array("form" => $form->__toString(), "message" => $message)); -    } else { -      print json_encode(array("form" => $form->__toString())); -    } -  } - -  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" => SafeString::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); +    print json_encode( +      array("grid" => self::_get_micro_thumb_grid($album, 0)->__toString(), +            "sort_column" => $album->sort_column, +            "sort_order" => $album->sort_order));    } -  public function edit_tags() { +  function sort_order($album_id, $col, $dir) {      access::verify_csrf(); -    $itemids = explode("|", $this->input->post("item")); -    $form = organize::get_tag_form($itemids); -    $old_tags = $form->tags->value; -    if ($form->validate()) { +    $album = ORM::factory("item", $album_id); +    access::required("view", $album); +    access::required("edit", $album); -      $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++; -        } -      } +    $options = album::get_sort_order_options(); +    if (!isset($options[$col])) { +      return;      } -    print json_encode(array("form" => $form->__toString(), "message" => t("Tags updated"))); -  } -  public function reset_edit_tags() { -    $itemids = $this->input->get("item"); +    $album->sort_column = $col; +    $album->sort_order = $dir; +    $album->save(); -    print organize::get_tag_form($itemids); +    print json_encode( +      array("grid" => self::_get_micro_thumb_grid($album, 0)->__toString(), +            "sort_column" => $album->sort_column, +            "sort_order" => $album->sort_order));    } -  private function _add_tag($new_tag, $itemids) { -    // Super lame security stopgap.  This code is going to get rewritten anyway. -    foreach ($itemids as $item_id) { -      $item = ORM::factory("item", $item_id); -      access::required("view", $item); -      access::required("edit", $item); -    } - -    $tag = ORM::factory("tag") -      ->where("name", $new_tag) -      ->find(); -    if ($tag->loaded) { -      $tag->count += count($itemids); -    } else { -      $tag->name = $new_tag; -      $tag->count = count($itemids); -    } -    $tag->save(); - -    $db = Database::instance(); -    foreach ($itemids as $item_id) { -      $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); -    } +  private static function _get_micro_thumb_grid($album, $offset) { +    $v = new View("organize_thumb_grid.html"); +    $v->album = $album; +    $v->offset = $offset; +    return $v;    } -  private function _delete_tag($new_tag, $itemids) { -    // Super lame security stopgap.  This code is going to get rewritten anyway. -    foreach ($itemids as $item_id) { -      $item = ORM::factory("item", $item_id); -      access::required("view", $item); -      access::required("edit", $item); -    } +  private static function _tree($album) { +    $v = new View("organize_tree.html"); +    $v->parents = $album->parents(); +    $v->album = $album; -    $tag = ORM::factory("tag") -      ->where("name", $new_tag) -      ->find(); -    $tag->count -= count($itemids); -    if ($tag->count > 0) { -      $tag->save(); +    if ($album->id == 1) { +      $v->peers = array($album);      } else { -      $tag->delete(); -    } - -    $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};"); +      $v->peers = $album->parent()->children(null, 0, array("type" => "album"));      } -  } - -  private function _getOperationDefinition($item, $operation) { -    switch ($operation) { -    case "move": -      return array("description" => -                     t("Move albums and photos to '%name'", array("name" => $item->title)), -                   "name" => t("Move to '%name'", array("name" => $item->title)), -                   "type" => "move", -                   "runningMsg" => t("Move in progress"), -                   "pauseMsg" => t("The move operation was paused"), -                   "resumeMsg" => t("The move operation was resumed")); -      break; - -    case "rearrange": -      return array("description" => t("Rearrange the order of albums and photos"), -                   "name" => t("Rearrange: %name", array("name" => $item->title)), -                   "type" => "rearrange", -                   "runningMsg" => t("Rearrange in progress"), -                   "pauseMsg" => t("The rearrange operation was paused"), -                   "resumeMsg" => t("The rearrange operation was resumed")); -      break; -    case "rotateCcw": -      return array("description" => t("Rotate the selected photos counter clockwise"), -                   "name" => t("Rotate images in %name", array("name" => $item->title)), -                   "type" => "rotateCcw", -                   "runningMsg" => t("Rotate Counter Clockwise in progress"), -                   "pauseMsg" => t("The rotate operation was paused"), -                   "resumeMsg" => t("The rotate operation was resumed")); -      break; - -    case "rotateCw": -      return array("description" => t("Rotate the selected photos clockwise"), -                   "name" => t("Rotate images in %name", array("name" => $item->title)), -                   "type" => "rotateCw", -                   "runningMsg" => t("Rotate Clockwise in progress"), -                   "pauseMsg" => t("The rotate operation was paused"), -                   "resumeMsg" => t("The rotate operation was resumed")); -      break; - -    case "delete": -      return array("description" => t("Delete selected photos / albums"), -                   "name" => t("Delete images in %name", array("name" => $item->title)), -                   "type" => "delete", -                   "runningMsg" => t("Delete images in progress"), -                   "pauseMsg" => t("The delete operation was paused"), -                   "resumeMsg" => t("The delete operation was resumed")); -      break; - -    case "albumCover": -      return array("description" => t("Reset Album Cover"), -                   "name" => t("Reset Album cover for %name", array("name" => $item->title)), -                   "type" => "albumCover", -                   "runningMsg" => t("Reset Album Cover in progress"), -                   "pauseMsg" => t("Reset album cover was paused"), -                   "resumeMsg" => t("Reset album cover was resumed")); -      break; - -    default: -      throw new Exception("Operation '$operation' is not implmented"); -    } +    return $v;    }  } diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index e58cd5a5..85168810 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -1,81 +1,79 @@ -/* @todo move to theme css */ +  /*******************************************************************   * Dialog wide stylings   */ -#gMessage { -  margin-bottom: .4em; +#gOrganizeDialog { +  text-align: left;  } -#gMessage .gInfo { -  background-color: transparent; -  background-image: none; -  padding-left: .4em; +#gOrganize { +  overflow: hidden;  } -#gOrganizeProgressDialog { -  text-align: left; +#gOrganize #bd { +  height: 100%; +} + +#gOrganize .yui-u { +  width: 75%; +} + +#gOrganize .yui-gf .first { +  width: 25%;  } -#gDialog .yui-gf div.first { -  width: 20%; +#gOrganize .yui-gf #gMessage { +  margin-bottom: .4em; +  width: 75%; +  white-space: nowrap;  } -#gDialog .yui-gf .yui-u { -  width: 80%; +#gOrganizeDetail { +  height: 100%; +} + +#gMessage .gInfo { +  font-weight: bold; +  padding-left: 2em;  }  /*******************************************************************   * Album Tree styling   */  #gOrganizeTreeContainer { -  overflow-y: auto; +  height: 100%; +  overflow: auto;    margin: 0 !important;    padding: 0 !important;  } -#gOrganizeAlbumDescription { -  height: 2em; -  overflow-y: auto; +#gOrganizeTreeContainer ul ul li { +  padding-left: 1.2em; +} + +.gAlbumText:hover { +  border: 1px dashed #999; +  padding: 1px;  } -.gBranchSelected { +#gOrganizeAlbumTree .selected {    background-color: #cfdeff !important;    border-bottom: 1px solid #999 !important;    display: block;    padding: .3em 0;  } -.gBranchDroppable { -  border: 1px dotted; +.gOrganizeAlbum span { +  cursor: pointer;  } -.gBranchText { +.gAlbumText {    cursor: pointer;    width: auto;  } - -.gBranchCollapsed { -  display: none; -} - -.gBranchEmpty { -  visibility: hidden; -} - -#gOrganizeTreeContainer ul ul li { -  padding-left: 1.2em; -} -  /*******************************************************************   * Album Panel Styles   */ - -#gMicroThumbUnselectAll, -#gMicroThumbSelectAll { -  font-size: 1em; -  font-weight: bold; -} -  #gMicroThumbPanel {    margin: 0 !important;    padding: 0 !important; @@ -83,200 +81,66 @@    border: 1px solid #999 !important;    border-top: none !important;    border-left: none !important; -  margin-left: -1em !important;    overflow-x: hidden;    overflow-y: auto;  }  #gMicroThumbGrid { -  padding: .5em; +  padding: 1em;  } -.gMicroThumbContainer { -  display: block; +.gMicroThumbGridCell {    float: left; -  font-size: .7em; -  height: 9em; -  margin-bottom: 1em; -  margin-left: 1em; -  opacity: .4; -  padding: 0 .5em; +  font-size: 0.8em; +  padding: .5em !important; +  opacity: .5; +  border-left: 1px hidden #13A; +  border-right: 1px hidden #13A;  }  .gMicroThumb { -  height: 9em; -  width: 9em; -  background-color: #fff;    display: block; -  float: left; +  height: 9em;    text-align: center; +  width: 9em;  } -#gMicroThumbPanel #gMicroThumbGrid .gAlbum { -  background-color: #e8e8e8; -} - -#gMicroThumbPanel #gMicroThumbGrid :hover { +.gMicroThumbGridCell.ui-state-selected {    opacity: 1;  } -.gMicroThumbContainer.ui-selected { -  opacity: 1; +.ui-selectable-lasso { +  z-index: 2000 !important; +  border: 1px dashed #13A;  } -#gDragHelper .gMicroThumbGrid { -  background-color: transparent; -  padding: 0; -  overflow: visible; +.gThumbnail { +  padding: .5em;  } -#gDragHelper .gMicroThumbContainer { -  display: block; -  margin: 0; -  padding: 0; +#gMicroThumbPanel #gMicroThumbGrid .gAlbum { +  background-color: #e8e8e8;  } -#gDragHelper .gMicroThumb { -  background-color: transparent; -  height: auto; -  width: auto; +#gMicroThumbPanel #gMicroThumbGrid :hover { +  opacity: 1;  } -  /**************************************************************** - * Organize Edit Drawer styling + * Organize Controls styling   */ -#gOrganizeEditDrawer { +#gOrganizeControls { +  padding-left: 8px;    background-color: #13A; -  width: 90%; -} - -#gOrganizeEditDrawerPanel { -  background-color: #fff; -  border: 1px solid #13A; -  display: none; -  height: 195px; -} - -#gOrganizeEditDrawerHandle { -  height: 30px; -} - -#gOrganizeEditHandleLeft { -  background-color: #FFF; -  float: left; -  height: 30px; -  width: 15px; -} - -#gOrganizeEditHandleButtonsMiddle, -#gOrganizeEditHandleButtonsLeft { -  float: left; -  height: 20px; -  padding: 2px 10px; -} - -#gOrganizeEditHandleButtonsMiddle { -  margin-left: 20px; -} - -#gOrganizeEditHandleButtonsMiddle a, -#gOrganizeEditHandleButtonsLeft a { -  float: left; -  margin: 0 2.5px; -} - -#gOrganizeEditHandleButtonsRight { -  float: right; -  height: 20px; -  padding: 2px 10px; -} - -#gOrganizeEditHandleButtonsRight a { -  float: left; -  margin: 0 2.5px; -} - -#gOrganizeEditHandleRight { -  background-color: #FFF; -  background-position: -15px 0; -  float: right; -  height: 30px; -  width: 15px; +  color: #ccc; +  width: 100% !important;  } -#gOrganizeFormButtons { -  bottom: 0.5em; -} - -#gOrganizeFormButtons .submit { +#gOrganizeControls select {    display: inline; -  float: none; -  left: 0.5em; -  position: relative;  } -/* yui-u gives 80% width, but then we wrap so do it ourselves */ -#gOrganizeEditForm { +#gOrganizeClose {    float: right; -  width: 79%; -  //  height: 100px; -} - -#gOrganizeFormThumbs { -  overflow: hidden; -} - -#gOrganizeFormThumbs div { -  margin: 0; -  text-align: center; -  background: transparent none repeat scroll 0 0; -} - -#gOrganizeFormThumbs .gMicroThumbContainer { -  display: block; -  float: left; -  opacity: 1; -  position: absolute; -} - -/**************************************************************** - * Organize Edit From tabs styling - */ -#gOrganizeEditForm.ui-tabs .ui-tabs-hide { -  display: block !important; -  left: -10000px; -  position: absolute; -} - -#gOrganizeEditForm.ui-widget { -  font-size: .75em; -} - -.gOrganizeEditPane { -  height: 135px; -  overflow-y: auto; -} - -.textbox, -.textarea { -  border: 1px solid #e8e8e8; -  border-top-color: #ccc; -  border-left-color: #ccc; -  color: #333; -  width: 100%; -} - -.textarea { -  height: 6em; -} - -.textbox  { -  height: 1.3em; -  width: 50% -} - -.gTagGroup { -  float:left; -  margin: .5em; +  margin-right: 12px;  } diff --git a/modules/organize/helpers/organize.php b/modules/organize/helpers/organize.php deleted file mode 100644 index 25284771..00000000 --- a/modules/organize/helpers/organize.php +++ /dev/null @@ -1,94 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access."); -/** - * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2009 Bharat Mediratta - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA. - */ -class organize_Core { -  static function get_general_edit_form($item) { -    $generalPane = new Forge("organize/__FUNCTION__", "", "post", -                             array("id" => "gEditGeneral", "ref" => "general")); -    // In this case we know there is only 1 item, but in general we should loop -    // and create multiple hidden items. -    $generalPane->hidden("item[]")->value($item->id); -    $generalPane->input("title")->label(t("Title"))->value($item->title); -    $generalPane->textarea("description")->label(t("Description"))->value($item->description); -    $generalPane->input("dirname")->label(t("Path Name"))->value($item->name) -      ->callback("item::validate_no_slashes") -      ->error_messages("no_slashes", t("The directory name can't contain a \"/\"")) -      ->callback("item::validate_no_trailing_period") -      ->error_messages("no_trailing_period", t("The directory name can't end in \".\"")) -      ->callback("item::validate_no_name_conflict") -      ->error_messages("conflict", t("The path name is not unique")); - -    return $generalPane; -  } - -  static function get_sort_edit_form($item) { -    $sortPane = new Forge("organize/__FUNCTION__", "", "post", -                          array("id" => "gEditSort", "ref" => "sort")); -    $sortPane->hidden("item[]")->value($item->id); -    $sortPane->dropdown("column", array("id" => "gAlbumSortColumn")) -      ->label(t("Sort by")) -      ->options(array("weight" => t("Order Added"), -                      "captured" => t("Capture Date"), -                      "created" => t("Creation Date"), -                      "title" => t("Title"), -                      "updated" => t("Updated Date"), -                      "view_count" => t("Number of views"), -                      "rand_key" => t("Random"))) -      ->selected($item->sort_column); -    $sortPane->dropdown("direction", array("id" => "gAlbumSortDirection")) -      ->label(t("Order")) -      ->options(array("ASC" => t("Ascending"), -                      "DESC" => t("Descending"))) -      ->selected($item->sort_order); - -    return $sortPane; -  } - -  static function get_tag_form($itemids) { -    $tagPane = new Forge("organize/__FUNCTION__", "", "post", -                             array("id" => "gEditTags", "ref" => "edit_tags")); -    $tagPane->hidden("item")->value(implode("|", $itemids)); -    $item_count = count($itemids); -    $ids = implode(", ", $itemids); - -    // Lame stopgap security check.  This code is going to get rewritten anyway. -    foreach ($itemids as $id) { -      $item = ORM::factory("item", $id); -      access::required("view", $item); -      access::required("edit", $item); -    } - -    $tags = Database::instance()->query( -      "SELECT t.name, COUNT(it.item_id) as count -         FROM {items_tags} it, {tags} t -        WHERE it.tag_id = t.id -          AND it.item_id in($ids) -       GROUP BY it.tag_id -       ORDER BY t.name ASC"); -    $taglist = array(); -    foreach ($tags as $tag) { -      $taglist[] = $tag->name . ($item_count > $tag->count ? "*" : ""); -    } -    $taglist = implode("; ", $taglist); -    $tagPane->textarea("tags")->label(t("Tags"))->value($taglist); - -    return $tagPane; -  } - -}
\ No newline at end of file diff --git a/modules/organize/helpers/organize_event.php b/modules/organize/helpers/organize_event.php index 99a28673..7d6b3e24 100644 --- a/modules/organize/helpers/organize_event.php +++ b/modules/organize/helpers/organize_event.php @@ -23,11 +23,11 @@ class organize_event_Core {      if ($item && access::can("edit", $item) && $item->is_album()) {        $menu->get("options_menu") -        ->append(Menu::factory("link") +        ->append(Menu::factory("dialog")          ->id("organize")          ->label(t("Organize Album"))          ->css_id("gOrganizeLink") -        ->url(url::site("organize/index/{$item->id}"))); +        ->url(url::site("organize/dialog/{$item->id}")));      }    }  } diff --git a/modules/organize/helpers/organize_task.php b/modules/organize/helpers/organize_task.php deleted file mode 100644 index dc474818..00000000 --- a/modules/organize/helpers/organize_task.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access."); -/** - * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2009 Bharat Mediratta - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA. - */ -class organize_task_Core { -  static function available_tasks() { -    // Return empty array so nothing appears in the maintenance screen -    return array(); -  } - -  static function run($task) { -    $context = unserialize($task->context); -    $taskType = $context["type"]; - -    try { -      $target = ORM::factory("item", $context["target"]); -      $total = count($context["items"]); -      $stop = min($total - $context["position"], $context["batch"]); -      $context["post_process"] = array(); -      for ($offset = 0; $offset < $stop; $offset++) { -        $current_id = $context["position"] + $offset; -        $id = $context["items"][$current_id]; -        switch ($taskType) { -        case "move": -          $source = ORM::factory("item", $id); -          access::required("view", $source); -          access::required("view", $target); -          access::required("edit", $source); -          access::required("edit", $target); - -          item::move($source, $target); -          break; - -        case "rearrange": -          $item = ORM::factory("item", $id); -          access::required("view", $item); -          access::required("edit", $item); - -          Database::instance() -            ->query("Update {items} set weight = {$context["position"]} where id=$id;"); -          break; - -        case "rotateCcw": -        case "rotateCw": -          $item = ORM::factory("item", $id); -          access::required("view", $item); -          access::required("edit", $item); - -          if ($item->is_photo()) { -            $context["post_process"]["reload"][] = -              self::_do_rotation($item, $taskType == "rotateCcw" ? -90 : 90); -          } -          break; - -        case "albumCover": -          $item = ORM::factory("item", $id); -          access::required("view", $item); -          access::required("view", $item->parent()); -          access::required("edit", $item->parent()); - -          item::make_album_cover($item); -          break; - -        case "delete": -          $item = ORM::factory("item", $id); -          access::required("view", $item); -          access::required("edit", $item); - -          $item->delete(); -          $context["post_process"]["remove"][] = array("id" => $id); -          break; - -        default: -          throw new Exception("Task '$taskType' is not implemented"); -        } -      } -      $context["position"] += $stop; -      $task->state = "success"; -    } catch(Exception $e) { -      $task->status = $e->getMessage(); -      $task->state = "error"; -      $task->save(); -      throw $e; -    } -    $task->context = serialize($context); -    $total = count($context["items"]); -    $task->percent_complete = $context["position"] / (float)$total * 100; -    $task->done = $context["position"] == $total || $task->state == "error"; -  } - -  private static function _do_rotation($item, $degrees) { -    // This code is copied from Quick_Controller::rotate -    graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); - -    list($item->width, $item->height) = getimagesize($item->file_path()); -    $item->resize_dirty= 1; -    $item->thumb_dirty= 1; -    $item->save(); - -    graphics::generate($item); - -    $parent = $item->parent(); -    if ($parent->album_cover_item_id == $item->id) { -      copy($item->thumb_path(), $parent->thumb_path()); -      $parent->thumb_width = $item->thumb_width; -      $parent->thumb_height = $item->thumb_height; -      $parent->save(); -    } -    list ($height, $width) = $item->scale_dimensions(90); -    $margin_top = (90 - $height) / 20; - -    return array("src" => $item->thumb_url() . "?rnd=" . rand(), -                 "id" => $item->id, -                 "marginTop" => "{$margin_top}em", "width" => $width, "height" => $height); -  } -}
\ No newline at end of file diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php index e4feba2b..61b6fe7d 100644 --- a/modules/organize/helpers/organize_theme.php +++ b/modules/organize/helpers/organize_theme.php @@ -19,9 +19,14 @@   */  class organize_theme {    static function head($theme) { -    // @tdo remove the addition css and organize.js (just here to test) -    $theme->script("organize_init.js"); -    $theme->script("organize.js"); -    $theme->css("organize.css"); +    $item = $theme->item(); +    if ($item && access::can("edit", $item) && $item->is_album()) { +      // @todo: Defer loading js/css until we're loading the organize dialog as <script> and +      // <link> elements so that we're not forcing them to be downloaded on every page view (which +      // is expensive in terms of browser latency).  When we do that, we'll have to figure out an +      // approach that lets us continue to use the Kohana cascading filesystem. +      $theme->script("organize.js"); +      $theme->css("organize.css"); +    }    }  } diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index f10cbcc9..04e14a2f 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -1,621 +1,210 @@ -/* - * @todo Trap resize of dialog and resize the child areas (tree, grid and edit form) - */ -var url; -var paused = false; -var task = null; -var transitItems = []; -var heightMicroThumbPanel; +(function($) { +  $.organize = { +    micro_thumb_draggable: { +      handle: ".ui-state-selected", +      distance: 10, +      cursorAt: { left: -10, top: -10}, +      appendTo: "#gMicroThumbPanel", +      helper: function(event, ui) { +        var selected = $(".ui-draggable.ui-state-selected img"); +        if (selected.length) { +          var set = $('<div class="gDragHelper"></div>') +		      .css({ +			zIndex: 2000, +			width: 80, +			height: Math.ceil(selected.length / 5) * 16 +		      }); +          var offset = $(this).offset(); +          var click = {left: event.pageX - offset.left, top: event.pageY - offset.top}; -// ************************************************************************** -// 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); +          selected.each(function(i) { +            var row = parseInt(i / 5); +            var j = i - (row * 5); +            var o = $(this).offset(); +            var copy = $(this).clone() +              .css({ +                width: $(this).width(), height: $(this).height(), display: "block", +                margin: 0, position: 'absolute', outline: '5px solid #fff', +                left: o.left - event.pageX, top: o.top - event.pageY +              }) +              .appendTo(set) +              .animate({ width: 10, height: 10, outlineWidth: 1, margin: 1, +			 left: (20 * j), top: (row * 20) }, 500); +          }); +          return set; +        } +        return null; +      }, -    $("li.ui-selected").each(function(i) { -      var clone = $(this).clone(); -      $(clone).attr("id", "drag_clone_" + $(this).attr("ref")); -      $("#gDragHelper ul").append(clone); -      $(clone).css("position", "absolute"); -      $(clone).css("top", beginTop); -      $(clone).css("left", beginLeft); -      $(clone).css("z-index", zindex--); -      $(this).hide(); +      start: function(event, ui) { +        $("#gMicroThumbPanel .ui-state-selected").hide(); +      }, -      var children = $(clone).find(".gMicroThumb .gThumbnail"); -      var width = new String(children.css("width")).replace(/[^0-9]/g,"") * .5; -      var height = new String(children.css("height")).replace(/[^0-9]/g,"") * .5; -      var marginTop = new String(children.css("margin-top")).replace(/[^\.0-9]/g,"") * .5; -      children.attr("width", width); -      children.attr("height", height); -      children.css("margin-top", marginTop); -      if (i < 9) { -        beginTop -= 5; -        beginLeft += 5; +      drag: function(event, ui) { +        var top = $("#gMicroThumbPanel").offset().top; +        var height = $("#gMicroThumbPanel").height(); +        if (ui.offset.top > height + top - 20) { +          $("#gMicroThumbPanel").get(0).scrollTop += 100; +        } else if (ui.offset.top < top + 20) { +          $("#gMicroThumbPanel").get(0).scrollTop = Math.max(0, $("#gMicroThumbPanel").get(0).scrollTop - 100); +        }        } -    }); -    return $("#gDragHelper"); -  }, -  stop: function(event, ui) { -    $("#gDragHelper li").each(function(i) { -      $("#thumb_" + $(this).attr("ref")).show(); -    }); -    $(".gMicroThumbContainer.ui-selected").css("z-index", null); -    $("#gDragHelper").remove(); -    $("#gPlaceHolder").remove(); -  } -}; +    }, -// Thumbnail Grid Droppable -var thumbDroppable =  { -  tolerance: "pointer", -  over: function(event, ui) { -    $("#gPlaceHolder").show(); -  }, -  out:  function(event, ui) { -    $("#gPlaceHolder").hide(); -  }, -  drop: function(event, ui) { -    $("#gDragHelper").hide(); -    $("#gPlaceHolder").hide(); -    var newOrder = ""; -    $("#gMicroThumbGrid .gMicroThumbContainer").each(function(i) { -      if ($(this).attr("id") == "gPlaceHolder") { -        $("#gDragHelper li").each(function(i) { -          newOrder += "&item[]=" + $(this).attr("ref"); +    content_droppable: { +      accept: "*", +      tolerance: "pointer", +      greedy: true, +      drop: function(event, ui) { +	var before_or_after = $(".currentDropTarget").css("borderLeftStyle") == "solid" ? "before" : "after"; +        $.organize.do_drop({ +          url: rearrange_url +	    .replace("__TARGET_ID__", $(".currentDropTarget").attr("ref")) +	    .replace("__ALBUM_ID__", $(".currentDropTarget").attr("ref")) +	    .replace("__BEFORE__", before_or_after), +          source: $(ui.helper).children("img")          }); -      } else if ($(this).css("display") != "none") { -        newOrder += "&item[]=" + $(this).attr("ref"); -      } else  { -        // If its not displayed then its one of the ones being moved so ignore.        } -    }); -    $("#gDragHelper li").each(function(i) { -      $("#gPlaceHolder").before($("#thumb_" + $(this).attr("ref")).show()); -    }); -    $.ajax({ -      data: newOrder, -      dataType: "json", -      success: operationCallback, -      type: "POST", -      url: get_organize_url("organize/startTask/rearrange", {item_id: item_id}) -    }); -  } -}; - -// Album Tree Droppable -var treeDroppable =  { -  tolerance: "pointer", -  greedy: true, -  hoverClass: "gBranchDroppable", -  drop: function(event, ui) { -    $("#gDragHelper").hide(); -    var targetItemId = $(this).attr("ref"); -    if ($(this).hasClass("gBranchSelected")) { -      $("#gMessage").empty().append(INVALID_DROP_TARGET); -      ui.draggable.trigger("stop", event); -      return false; -    } -    var postData = serializeItemIds("#gDragHelper li"); -    var okToMove = true; -    $("#gDragHelper li").each(function(i) { -      okToMove &= targetItemId != $(this).attr("ref"); -    }); -    if (!okToMove) { -      $("#gMessage").empty().append(INVALID_DROP_TARGET); -      ui.draggable.trigger("stop", event); -      return false; -    } -    $("#gDragHelper li").each(function(i) { -      $("#thumb_" + $(this).attr("ref")).remove(); -    }); -    $.ajax({ -      data: postData, -      dataType: "json", -      success: operationCallback, -      type: "POST", -      url: get_organize_url("organize/startTask/move", {item_id: targetItemId}) -    }); -    return true; -  } -}; - -// Selectable -var selectable = { -  filter: ".gMicroThumbContainer", -  selected: function(event, ui) { -    setDrawerButtonState(); -  }, -  unselected: function(event, ui) { -    setDrawerButtonState(); -  }, -  stop: function(event, ui) { -    getEditForm(); -  } -}; - -// ************************************************************************** -// Event Handlers -// MicroThumbContainer mouseup -var onMicroThumbContainerMouseup = function(event) { -  // For simplicity always remove the ui-selected class.  If it was unselected -  // it will get added back -  $(this).toggleClass("ui-selected"); - -  setDrawerButtonState(); -  if ($("#gMicroThumbGrid li.ui-selected").length > 0) { -    getEditForm(); -  } -}; +    }, -// MicroThumbContainer mousemove -var onMicroThumbContainerMousemove = function(event) { -  if ($("#gDragHelper").length > 0 && $(this).attr("id") != "gPlaceHolder") { -    if (event.pageX < $(this).offset().left + $(this).width() / 2) { -      $(this).before($("#gPlaceHolder")); -    } else { -      $(this).after($("#gPlaceHolder")); -    } -    var container = $("#gMicroThumbPanel").get(0); -    var scrollHeight = container.scrollHeight; -    var scrollTop = container.scrollTop; -    var height = $(container).height(); -    if (event.pageY > height + scrollTop) { -      container.scrollTop = this.offsetTop; -    } else if (event.pageY < scrollTop) { -      container.scrollTop -= height; -    } -  } -}; - -// Handle click events on the buttons on the drawer handle -function drawerHandleButtonsClick(event) { -  event.preventDefault(); -  if (!$(this).attr("disabled")) { -    var operation = $(this).attr("ref"); -    switch (operation) { -    case "edit": -    case "close": -      $("#gOrganizeEditDrawerPanel").animate( -        {"height": "toggle", "display": "block"}, -        {duration: "fast", -         complete: function() { -           setSelectedThumbs(); -           if (operation == "close") { -             $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "inline-block"); -             $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "none"); -             $("#gOrganizeEditHandleButtonsMiddle a").css("display", "none"); -           } else { -             $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "none"); -             $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "inline-block"); -             $("#gOrganizeEditHandleButtonsMiddle a").css("display", "inline-block"); -           } -         }, -         step: function() { -           $("#gMicroThumbPanel").height(heightMicroThumbPanel - $(this).height()); -         } -      }); -      break; -    case "select-all": -      $("#gMicroThumbGrid li").addClass("ui-selected"); -      $("#gMicroThumbSelectAll").hide(); -      $("#gMicroThumbUnselectAll").show(); -      setDrawerButtonState(); -      getEditForm(); -      break; -    case "unselect-all": -      $("#gMicroThumbGrid li").removeClass("ui-selected"); -      $("#gMicroThumbSelectAll").show(); -      $("#gMicroThumbUnselectAll").hide(); -      setDrawerButtonState(); -      break; -    case "done": -      $("#gDialog").dialog("close"); -      break; -    case "submit": -      var currentTab = $("#gOrganizeEditForm").tabs("option", "selected"); -      var form = $("#pane-"+currentTab+" form"); -      var url = $(form).attr("action") -        .replace("__FUNCTION__", $(form).attr("ref")); -      $.ajax({ -        data: $(form).serialize(), -        dataType: "json", -        success: function (data, textStatus) { -          $("#pane-"+currentTab).children("form").replaceWith(data.form); -          if (data.message) { -            $("#gMessage").empty().append("<div class='gSuccess'>" + data.message + "</div>"); -          } -        }, -        type: "POST", -        url: url -      }); -      break; -    case "reset": -      currentTab = $("#gOrganizeEditForm").tabs("option", "selected"); -      form = $("#pane-"+currentTab+" form"); -      $.ajax({ -        data: serializeItemIds("#gMicroThumbPanel li.ui-selected"), -        dataType: "html", -        success: function (data, textStatus) { -          $("#pane-"+currentTab + " form").replaceWith(data); -        }, -        type: "GET", -        url: $(form).attr("action").replace("__FUNCTION__", "reset_" + $(form).attr("ref")) -      }); -      break; -    case "delete": -      if (!confirm(CONFIRM_DELETE)) { -        break; -      } -    default: -      $.ajax({ -        data: serializeItemIds("#gMicroThumbPanel li.ui-selected"), -        dataType: "json", -        success: operationCallback, -        type: "POST", -        url: get_organize_url("organize/startTask/" + operation, {item_id: item_id}) -      }); -      break; -    } -  } -}; - -// ************************************************************************** -// AJAX Callbacks -// MicroThumbContainer click -var getMicroThumbsCallback = function(json, textStatus) { -  if (json.count > 0) { -    $("#gMicroThumbGrid").append(json.data); -    retrieveMicroThumbs(); -    $(".gMicroThumbContainer").mouseup(onMicroThumbContainerMouseup); -    $(".gMicroThumbContainer").mousemove(onMicroThumbContainerMousemove); -    $(".gMicroThumbContainer").draggable(draggable); -  } -}; - -var operationCallback = function (data, textStatus) { -  var done = false; -  if (!paused) { -    createProgressDialog(data.runningMsg); -    task = data.task; -    task.pauseMsg = data.pauseMsg; -    task.resumeMsg = data.resumeMsg; -    done = data.task.done; -  } -  $(".gMicroThumbContainer").draggable("disable"); -  paused = false; -  while (!done && !paused) { -    $.ajax({async: false, -      success: function(data, textStatus) { -        $(".gProgressBar").progressbar("value", data.task.percent_complete); -        done = data.task.done; -        if (data.task.post_process.reload) { -          $.each(data.task.post_process.reload, function() { -            var selector = "#gMicroThumb-" + this.id + " img"; -            $(selector).attr("height", this.height); -            $(selector).attr("width", this.width); -            $(selector).attr("src", this.src); -            $(selector).css("margin-top", this.marginTop); +    branch_droppable: { +      accept: "*", +      tolerance: "pointer", +      greedy: true, +      drop: function(event, ui) { +        if ($(event.target).hasClass("gViewOnly")) { +          $(".ui-state-selected").show(); +          $(".gMicroThumbGridCell").css("borderStyle", "none"); +        } else { +          $.organize.do_drop({ +            url: move_url.replace("__ALBUM_ID__", $(event.target).attr("ref")), +            source: $(ui.helper).children("img")            });          } -        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); +    do_drop: function(options) { +      $("#gMicroThumbPanel").selectable("destroy"); +      var source_ids = []; +      $(options.source).each(function(i) { +        source_ids.push($(this).attr("ref")); +      }); -  $("#gMicroThumbPanel").height(heightMicroThumbPanel); -  $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); +      if (source_ids.length) { +	$.post(options.url, +	       { "source_ids[]": source_ids }, +	       function(data) { $.organize._refresh(data); }, +	      "json"); +      } +    }, -  $(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); -  $(".gBranchText").droppable(treeDroppable); -  $(".gBranchText").click(organizeOpenFolder); -  retrieveMicroThumbs(item_id); -  //showLoading("#gDialog"); +    _refresh: function(data) { +      if (data.tree) { +        $("#gOrganizeAlbumTree").html(data.tree); +      } +      if (data.grid) { +        $("#gMicroThumbGrid").html(data.grid); +        $("#gOrganizeSortColumn").attr("value", data.sort_column); +        $("#gOrganizeSortOrder").attr("value", data.sort_order); +      } +      $.organize.set_handlers(); +    }, -  $("#gMicroThumbPanel").droppable(thumbDroppable); -  $("#gMicroThumbPanel").selectable(selectable); -  $("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick); -} +    mouse_move_handler: function(event) { +      if ($(".gDragHelper").length) { +        $(".gMicroThumbGridCell").css("borderStyle", "hidden"); +        $(".currentDropTarget").removeClass("currentDropTarget"); +        var borderStyle = event.pageX < $(this).offset().left + $(this).width() / 2 ? +          "borderLeftStyle" : "borderRightStyle"; +        $(this).css(borderStyle, "solid"); +        $(this).addClass("currentDropTarget"); +      } +    }, -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); -} +    /** +     * Dynamically initialize the organize dialog when it is displayed +     */ +    init: function(data) { +      var self = this; +      // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 (target 1.8?) +      $(".sf-menu li.sfHover ul").css("z-index", 68); +      $("#gDialog").dialog("option", "zIndex", 70); +      $("#gDialog").bind("dialogopen", function(event, ui) { +        $("#gOrganize").height($("#gDialog").innerHeight() - 20); +        $("#gMicroThumbPanel").height($("#gDialog").innerHeight() - 90); +        $("#gOrganizeAlbumTree").height($("#gDialog").innerHeight() - 59); +      }); -function 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(); -} +      $("#gDialog").bind("dialogclose", function(event, ui) { +        window.location.reload(); +      }); -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(); -} +      $("#gDialog #gOrganizeClose").click(function(event) { +        $("#gDialog").dialog("close"); +      }); -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; -} +      $("#gOrganizeSortColumn,#gOrganizeSortOrder").change(function(event) { +	$.organize.resort($("#gOrganizeSortColumn").attr("value"), $("#gOrganizeSortOrder").attr("value")); +      }); -/** - * 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"); +      $.organize.set_handlers(); +    }, -    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"); -  } -} +    set_handlers: function() { +      $("#gMicroThumbPanel").selectable({filter: ".gMicroThumbGridCell"}); +      $("#gMicroThumbPanel").droppable($.organize.content_droppable); -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--); +      $(".gMicroThumbGridCell").draggable($.organize.micro_thumb_draggable); +      $(".gMicroThumbGridCell").mousemove($.organize.mouse_move_handler); +      $(".gOrganizeAlbum").droppable($.organize.branch_droppable); +      $(".gAlbumText").click($.organize.show_album); +    }, -    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"); +    /** +     * When the text of a selection is clicked, then show that albums contents +     */ +    show_album: function(event) { +      event.preventDefault(); +      if ($(event.currentTarget).hasClass("selected")) { +        return;        } -    }); -  } 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; +      var parent = $(event.currentTarget).parents(".gOrganizeBranch"); +      if ($(parent).hasClass("gViewOnly")) { +        return;        } -  }; -} +      $("#gMicroThumbPanel").selectable("destroy"); +      var id = $(event.currentTarget).attr("ref"); +      $("#gOrganizeAlbumTree .selected").removeClass("selected"); +      $(".gAlbumText[ref=" + id + "]").addClass("selected"); +      var url = $("#gMicroThumbPanel").attr("ref").replace("__ITEM_ID__", id).replace("__OFFSET__", 0); +      $.get(url, {}, +	    function(data) { +	      $("#gMicroThumbGrid").html(data.grid); +	      $("#gOrganizeSortColumn").attr("value", data.sort_column); +              $("#gOrganizeSortOrder").attr("value", data.sort_order); +              $.organize.set_handlers(); +	    }, +	    "json"); +    }, -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() -  }); -} +    /** +     * Change the sort order. +     */ +    resort: function(column, dir) { +      var url = sort_order_url +        .replace("__ALBUM_ID__", $("#gOrganizeAlbumTree .selected").attr("ref")) +        .replace("__COL__", column) +        .replace("__DIR__", dir); +      $.get(url, {}, +	    function(data) { +	      $("#gMicroThumbGrid").html(data.grid); +              $("#gOrganizeSortColumn").attr("value", data.sort_column); +              $("#gOrganizeSortOrder").attr("value", data.sort_order); +	      $.organize.set_handlers(); +	    }, +	    "json"); +    } +  }; +})(jQuery); diff --git a/modules/organize/js/organize_init.js b/modules/organize/js/organize_init.js deleted file mode 100644 index ed036fdb..00000000 --- a/modules/organize/js/organize_init.js +++ /dev/null @@ -1,29 +0,0 @@ -$("document").ready(function() { -  $("#gOrganizeLink").click(function(event) { -    event.preventDefault(); -    var href = event.target.href; - -    $("body").append('<div id="gDialog"></div>'); - -    $("#gDialog").dialog({ -      autoOpen: false, -      autoResize: false, -      modal: true, -      resizable: false, -      close: function () { -        $("#gDialog").trigger("organize_close"); -        $("#gDialog").dialog("destroy").remove(); -      }, -      zIndex: 75 -    }); - -    //showLoading("#gDialog"); - -    $.get(href, function(data) { -      $("#gDialog").html(data); -    }); -    return false; -  }); -}); - - diff --git a/modules/organize/views/organize.html.php b/modules/organize/views/organize.html.php deleted file mode 100644 index d2f0aa8c..00000000 --- a/modules/organize/views/organize.html.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access.") ?> -<!-- ?= html::script("modules/organize/js/organize.js") ? --> -<script> -  var FATAL_ERROR = "<?= t("Fatal Error")->for_js() ?>"; -  var PAUSE_BUTTON = "<?= t("Pause")->for_js() ?>"; -  var RESUME_BUTTON = "<?= t("Resume"->for_js()) ?>"; -  var CANCEL_BUTTON = "<?= t("Cancel")->for_js() ?>"; -  var INVALID_DROP_TARGET = "<div class=\"gError\"><?= t("Drop cancelled as it would result in a recursive move")->for_js() ?></div>"; -var CONFIRM_DELETE = "<?= t("Do you really want to delete the selected albums and/or photos")->for_js() ?>" -  var item_id = <?= $item->id ?>; - -  var csrf = <?= json_encode($csrf) ?>; -  var rearrangeUrl = "<?= url::site("__URI__/__ITEM_ID____TASK_ID__?csrf=$csrf")->for_js() ?>"; -  $("#doc3").ready(function() { -    organize_dialog_init(); -  }); -</script> -<fieldset style="display: none"> -  <legend><?= t("Organize %name", array("name" => SafeString::purify($item->title))) ?></legend> -</fieldset> -<div id="doc3" class="yui-t7"> -  <div id="bd"> -    <div class="yui-gf"> -      <div class="yui-u first"> -        <h3><?= t("Albums") ?></h3> -      </div> -      <div id="gMessage" class="yui-u"> -        <div class="gInfo"><?= t("Select one or more items to edit; drag and drop items to re-order or move between albums") ?></div> -      </div> -    </div> -    <div class="yui-gf"> -      <div id="gOrganizeTreeContainer" class="yui-u first"> -        <?= $album_tree ?> -      </div> -      <div id="gMicroThumbPanel" class="yui-u" -           ref="<?= url::site("organize/content/__ITEM_ID__?width=__WIDTH__&height=__HEIGHT__&offset=__OFFSET__") ?>"> -        <ul id="gMicroThumbGrid"></ul> -      </div> -      <div id="gOrganizeEditDrawer" class="yui-u"> -        <div id="gOrganizeEditDrawerPanel" class="yui-gf"> -          <div id="gOrganizeFormThumbs" class="yui-u first"> -            <ul id="gOrganizeFormThumbStack" /> -          </div> -          <div id="gOrganizeEditForm"> -          </div> -        </div> -        <div id="gOrganizeEditDrawerHandle"> -          <?= $button_pane ?> -        </div> -      </div> -    </div> -  </div> -</div> diff --git a/modules/organize/views/organize_album.html.php b/modules/organize/views/organize_album.html.php deleted file mode 100644 index 4933ed32..00000000 --- a/modules/organize/views/organize_album.html.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access.") ?> -<ul> -  <li class="gOrganizeBranch ui-icon-left" ref="<?= $album->id ?>"> -    <span id="gOrganizeIcon-<?= $album->id ?>" ref="<?= $album->id ?>" -          class="ui-icon <?= $album_icon ?> <?= $album_icon ? "" : "gBranchEmpty" ?>"> -    </span> - -    <div id="gOrganizeBranch-<?= $album->id ?>" ref="<?= $album->id ?>" -          class="<?= $selected ? "gBranchSelected" : "" ?> gBranchText"> -      <?= SafeString::of($album->title) ?> -    </div> -    <div id="gOrganizeChildren-<?= $album->id ?>" -          class="<?= $album_icon == "ui-icon-plus" ? "gBranchCollapsed" : "" ?>"> -      <?= $children ?> -    <div> -  </li> -</ul> diff --git a/modules/organize/views/organize_button_pane.html.php b/modules/organize/views/organize_button_pane.html.php deleted file mode 100644 index c5839a44..00000000 --- a/modules/organize/views/organize_button_pane.html.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access.") ?> -<div id="gOrganizeEditHandleButtonsLeft"> -  <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="edit" -     disabled="1" title="<?= t("Open Drawer") ?>"> -    <span class="ui-icon ui-icon-arrowthickstop-1-n"><?= t("Open Drawer") ?></span> -  </a> - -  <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="close" -     disabled="1" title="<?= t("Close Drawer") ?>" style="display: none"> -    <span class="ui-icon ui-icon-arrowthickstop-1-s"><?= t("Close Drawer") ?></span> -  </a> - -  <? if (graphics::can("rotate")): ?> -  <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="rotateCcw" -     disabled="1" title="<?= t("Rotate 90 degrees counter clockwise") ?>"> -    <span class="ui-icon ui-icon-rotate-ccw"><?= t("Rotate 90 degrees counter clockwise") ?></span> -  </a> - -  <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="rotateCw" -     disabled="1" title="<?= t("Rotate 90 degrees clockwise") ?>"> -    <span class="ui-icon ui-icon-rotate-cw"> <?= t("Rotate 90 degrees clockwise") ?></span> -  </a> -  <? endif ?> - -  <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="albumCover" -     disabled="1" title="<?= t("Choose this photo as the album cover") ?>"> -    <span class="ui-icon ui-icon-star"><?= t("Choose this photo as the album cover") ?></span> -  </a> - -  <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="delete" -     disabled="1" title="<?= t("Delete selection") ?>"> -    <span class="ui-icon ui-icon-trash"><?= t("Delete selection") ?></span> -  </a> -</div> -<div id="gOrganizeEditHandleButtonsMiddle"> -  <a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="submit" -     title="<?= t("Apply Changes") ?>" style="display: none" > -    <span class="ui-icon ui-icon-check"><?= t("Apply Changes") ?></span> -  </a> - -  <a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="reset" -     title="<?= t("Reset Form") ?>" style="display: none" > -    <span class="ui-icon ui-icon-closethick"><?= t("Reset Form") ?></span> -  </a> -</div> -<div id="gOrganizeEditHandleButtonsRight"> -  <a id="gMicroThumbSelectAll" href="#" ref="select-all" class="gButtonLink ui-corner-all ui-state-default"><?= t("Select all") ?></a> -  <a id="gMicroThumbUnselectAll" href="#" ref="unselect-all" style="display: none" class="gButtonLink ui-corner-all ui-state-default"><?= t("Deselect all") ?></a> -  <a id="gMicroThumbDone" href="#" ref="done" class="gButtonLink ui-corner-all ui-state-default"><?= t("Close") ?></a> -</div> diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php new file mode 100644 index 00000000..b03c066c --- /dev/null +++ b/modules/organize/views/organize_dialog.html.php @@ -0,0 +1,47 @@ +<?php defined("SYSPATH") or die("No direct script access.") ?> +<script type="text/javascript"> +  var move_url = "<?= url::site("organize/move_to/__ALBUM_ID__?csrf=$csrf") ?>"; +  var rearrange_url = "<?= url::site("organize/rearrange/__TARGET_ID__/__BEFORE__?csrf=$csrf") ?>"; +  var sort_order_url = "<?= url::site("organize/sort_order/__ALBUM_ID__/__COL__/__DIR__?csrf=$csrf") ?>"; +</script> +<div id="gOrganize" class="gDialogPanel"> +  <h1 style="display:none"><?= t("Organize %name", array("name" => p::purify($album->title))) ?></h1> +  <div id="bd"> +    <div class="yui-gf"> +      <div class="yui-u first"> +        <h3><?= t("Albums") ?></h3> +      </div> +      <div id="gMessage" class="yui-u"> +        <div class="gInfo"><?= t("Drag and drop photos to re-order or move between albums") ?></div> +      </div> +    </div> +    <div id="gOrganizeContentPane" class="yui-gf"> +      <div id="gOrganizeTreeContainer" class="yui-u first"> +        <ul id="gOrganizeAlbumTree"> +          <?= $album_tree ?> +        </ul> +      </div> +      <div id="gOrganizeDetail" class="yui-u"> +        <div id="gMicroThumbPanel" +             ref="<?= url::site("organize/album/__ITEM_ID__/__OFFSET__") ?>"> +          <ul id="gMicroThumbGrid"> +            <?= $micro_thumb_grid ?> +          </ul> +        </div> +        <div id="gOrganizeControls"> +          <a id="gOrganizeClose" href="#" ref="done" +             class="gButtonLink ui-corner-all ui-state-default"><?= t("Close") ?></a> +          <form> +            <?= t("Sort order") ?> +            <?= form::dropdown(array("id" => "gOrganizeSortColumn"), album::get_sort_order_options(), $album->sort_column) ?> +            <?= form::dropdown(array("id" => "gOrganizeSortOrder"), array("ASC" => "Ascending", "DESC" => "Descending"), $album->sort_order) ?> +          </form> +        </div> +      </div> +    </div> +  </div> +</div> + +<script type="text/javascript"> +  $("#gOrganize").ready($.organize.init); +</script> diff --git a/modules/organize/views/organize_edit.html.php b/modules/organize/views/organize_edit.html.php deleted file mode 100644 index 1adf290f..00000000 --- a/modules/organize/views/organize_edit.html.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access.") ?> -<ul> -<? foreach ($panes as $idx => $pane): ?> -  <li><a href="#pane-<?= $idx ?>"><?= $pane["label"] ?></a></li> -<? endforeach?> -</ul> - -<? if (count($panes) > 0): ?> -  <? foreach ($panes as $idx => $pane): ?> -    <div id="pane-<?= $idx ?>" class="gOrganizeEditPane ui-tabs-hide"><?= $pane["content"] ?></div> -  <? endforeach?> -<? else: ?> -<div class="gWarning"><?= t("No Edit pages apply to the selected items") ?></div> -<? endif ?>
\ No newline at end of file diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php index c80696ad..31dc9af5 100644 --- a/modules/organize/views/organize_thumb_grid.html.php +++ b/modules/organize/views/organize_thumb_grid.html.php @@ -1,12 +1,22 @@  <?php defined("SYSPATH") or die("No direct script access.") ?> -<? foreach ($children as $i => $child): ?> -<? $item_class = "gPhoto"; ?> -<? if ($child->is_album()): ?> -  <? $item_class = "gAlbum"; ?> -<? endif ?> -<li id="thumb_<?= $child->id ?>" class="gMicroThumbContainer" ref="<?= $child->id ?>"> -  <div id="gMicroThumb-<?= $child->id ?>" class="gMicroThumb <?= $item_class ?>"> -    <?= $child->thumb_img(array("class" => "gThumbnail"), $thumbsize, true) ?> +<? foreach ($album->children(25, $offset) as $child): ?> +<li class="gMicroThumbGridCell" ref="<?= $child->id ?>"> +  <div id="gMicroThumb_<?= $child->id ?>" +       class="gMicroThumb <?= $child->is_album() ? "gAlbum" : "gPhoto" ?>"> +    <?= $child->thumb_img(array("class" => "gThumbnail", "ref" => $child->id), 90, true) ?>    </div>  </li>  <? endforeach ?> + +<? if ($album->children_count() > $offset): ?> +<script> +  setTimeout(function() { +    $.get("<?= url::site("organize/content/$album->id/" . ($offset + 25)) ?>", +      function(data) { +        $("#gMicroThumbGrid").append(data); +        $.organize.set_handlers(); +      } +    ); +  }, 50); +</script> +<? endif ?> diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php index d2cdd957..36f900ac 100644 --- a/modules/organize/views/organize_tree.html.php +++ b/modules/organize/views/organize_tree.html.php @@ -1,4 +1,44 @@  <?php defined("SYSPATH") or die("No direct script access.") ?> -<? foreach ($children as $i => $child): ?> -<? endforeach ?> +<? foreach ($parents as $parent): ?> +<li class="gOrganizeAlbum ui-icon-left <?= access::can("edit", $parent) ? "" : "gViewOnly" ?>" +    ref="<?= $parent->id ?>"> +  <span class="ui-icon ui-icon-minus"> +  </span> +  <span class="gAlbumText" ref="<?= $parent->id ?>"> +    <?= p::clean($parent->title) ?> +  </span> +  <ul class="ui-icon-plus"> +    <? endforeach ?> + +    <? foreach ($peers as $peer): ?> +    <li class="gOrganizeAlbum ui-icon-left <?= access::can("edit", $peer) ? "" : "gViewOnly" ?>" +        ref="<?= $peer->id ?>"> +      <span class="ui-icon <?= $peer->id == $album->id ? "ui-icon-minus" : "ui-icon-plus" ?>"> +      </span> +      <span class="gAlbumText <?= $peer->id == $album->id ? "selected" : "" ?>" +            ref="<?= $peer->id ?>"> +        <?= p::clean($peer->title) ?> +      </span> +      <? if ($peer->id == $album->id): ?> +      <ul class="ui-icon-plus"> +        <? foreach ($album->children(null, 0, array("type" => "album")) as $child): ?> +        <li class="gOrganizeAlbum ui-icon-left <?= access::can("edit", $child) ? "" : "gViewOnly" ?>" +            ref="<?= $child->id ?>"> +          <span class="ui-icon ui-icon-plus"> +          </span> +          <span class="gAlbumText" +                ref="<?= $child->id ?>"> +            <?= p::clean($child->title) ?> +          </span> +        </li> +        <? endforeach ?> +      </ul> +      <? endif ?> +    </li> +    <? endforeach ?> + +    <? foreach ($parents as $parent): ?> +  </ul> +</li> +<? endforeach ?> | 
