1
0

Merge branch 'master' of github.com:gallery/gallery3-contrib

This commit is contained in:
Bharat Mediratta 2010-09-06 18:24:54 -07:00
commit b92e0ee162
19 changed files with 528 additions and 179 deletions

View File

@ -1,3 +1,3 @@
name = "Autorotate"
description = "Rotate an image automatically on upload based on EXIF data"
version = 1
version = 2

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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

View File

@ -27,10 +27,14 @@ class Admin_Photoannotation_Controller extends Admin_Controller {
$form = $this->_get_form();
if ($form->validate()) {
module::set_var(
"photoannotation", "showusers", $form->photoannotation->showusers->value, true);
module::set_var(
"photoannotation", "showfaces", $form->photoannotation->showfaces->value, true);
module::set_var(
"photoannotation", "shownotes", $form->photoannotation->shownotes->value, true);
module::set_var(
"photoannotation", "fullname", $form->photoannotation->fullname->value, true);
message::success(t("Your settings have been saved."));
url::redirect("admin/photoannotation");
}
@ -47,10 +51,14 @@ class Admin_Photoannotation_Controller extends Admin_Controller {
private function _get_form() {
$form = new Forge("admin/photoannotation/handler", "", "post", array("id" => "g-admin-form"));
$group = $form->group("photoannotation")->label(t("Photo annotation settings"));
$group->checkbox("showusers")->label(t("Show face annotation below photo."))
->checked(module::get_var("photoannotation", "showusers", false));
$group->checkbox("showfaces")->label(t("Show face annotation below photo."))
->checked(module::get_var("photoannotation", "showfaces", false));
$group->checkbox("shownotes")->label(t("Show note annotations below photo."))
->checked(module::get_var("photoannotation", "shownotes", false));
$group->checkbox("fullname")->label(t("Show full name of a user instead of the username on annotations (username will be dispayed for users without a full name)."))
->checked(module::get_var("photoannotation", "fullname", false));
$form->submit("submit")->value(t("Save"));
return $form;
}

View File

@ -18,23 +18,22 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class photoannotation_Controller extends Controller {
public function save($item_data) {
public function save($item_id) {
// Prevent Cross Site Request Forgery
access::verify_csrf();
//Get form data
$item = ORM::factory("item", $item_data);
$noteid = $_POST["noteid"];
$item = ORM::factory("item", $item_id);
$annotate_id = $_POST["noteid"];
$notetype = $_POST["notetype"];
$str_y1 = $_POST["top"];
$str_x1 = $_POST["left"];
$str_y2 = $_POST["height"] + $str_y1; //Annotation uses area size, tagfaces uses positions
$str_x2 = $_POST["width"] + $str_x1; //Annotation uses area size, tagfaces uses positions
$str_face_title = $_POST["text"];
$item_title = $_POST["text"];
$tag_data = $_POST["tagsList"];
$str_face_description = $_POST["desc"];
$user_id = $_POST["userlist"];
$description = $_POST["desc"];
$redir_uri = url::abs_site("{$item->type}s/{$item->id}");
//Add tag to item, create tag if not exists
if ($tag_data != "") {
$tag = ORM::factory("tag")->where("name", "=", $tag_data)->find();
@ -42,7 +41,6 @@ class photoannotation_Controller extends Controller {
$tag->name = $tag_data;
$tag->count = 0;
}
$tag->add($item);
$tag->count++;
$tag->save();
@ -50,102 +48,80 @@ class photoannotation_Controller extends Controller {
} else {
$tag_data = -1;
}
// Decide if we are saving a face or a note.
if ($noteid == "new") {
if ($tag_data == -1) {
if ($str_face_title == "") {
message::error(t("Please select a Tag or specify a Title."));
//Save annotation
if ($annotate_id == "new") { //This is a new annotation
if ($user_id > -1) { //Save user
$this->_saveuser($user_id, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
} elseif ($tag_data > -1) { //Conversion user -> face
$this->_saveface($tag_data, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
} elseif ($item_title != "") { //Conversion user -> note
$this->_savenote($item_title, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
} else { //Somethings wrong
message::error(t("Please select a User or Tag or specify a Title."));
url::redirect($redir_uri);
return;
}
} else { //This is an update to an existing annotation
switch ($notetype) {
case "user": //the original annotation is a user
$updateduser = ORM::factory("items_user") //load the existing user
->where("id", "=", $annotate_id)
->find();
if ($user_id > -1) { //Conversion user -> user
$this->_saveuser($user_id, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description, $annotate_id);
} elseif ($tag_data > -1) { //Conversion user -> face
$this->_saveface($tag_data, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
$updateduser->delete(); //delete old user
} elseif ($item_title != "") { //Conversion user -> note
$this->_savenote($item_title, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
$updateduser->delete(); //delete old user
} else { //Somethings wrong
message::error(t("Please select a User or Tag or specify a Title."));
url::redirect($redir_uri);
return;
}
break;
case "face": //the original annotation is a face
$updatedface = ORM::factory("items_face") //load the existing user
->where("id", "=", $annotate_id)
->find();
if ($user_id > -1) { //Conversion face -> user
$this->_saveuser($user_id, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
$updatedface->delete(); //delete old face
} elseif ($tag_data > -1) { //Conversion face -> face
$this->_saveface($tag_data, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description, $annotate_id);
} elseif ($item_title != "") { //Conversion face -> note
$this->_savenote($item_title, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
$updatedface->delete(); //delete old face
} else { //Somethings wrong
message::error(t("Please select a User or Tag or specify a Title."));
url::redirect($redir_uri);
return;
}
break;
case "note": //the original annotation is a note
$updatednote = ORM::factory("items_note") //load the existing user
->where("id", "=", $annotate_id)
->find();
if ($user_id > -1) { //Conversion note -> user
$this->_saveuser($user_id, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
$updatednote->delete(); //delete old note
} elseif ($tag_data > -1) { //Conversion note -> face
$this->_saveface($tag_data, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description);
$updatednote->delete(); //delete old note
} elseif ($item_title != "") { //Conversion note -> note
$this->_savenote($item_title, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description, $annotate_id);
} else { //Somethings wrong
message::error(t("Please select a User or Tag or specify a Title."));
url::redirect($redir_uri);
return;
}
break;
default:
message::error(t("Please select a User or Tag or specify a Title."));
url::redirect($redir_uri);
return;
}
//Save note
$newnote = ORM::factory("items_note");
$newnote->item_id = $item_data;
$newnote->x1 = $str_x1;
$newnote->y1 = $str_y1;
$newnote->x2 = $str_x2;
$newnote->y2 = $str_y2;
$newnote->title = $str_face_title;
$newnote->description = $str_face_description;
$newnote->save();
} else {
// Save the new face to the database.
$newface = ORM::factory("items_face");
$newface->tag_id = $tag_data;
$newface->item_id = $item_data;
$newface->x1 = $str_x1;
$newface->y1 = $str_y1;
$newface->x2 = $str_x2;
$newface->y2 = $str_y2;
$newface->description = $str_face_description;
$newface->save();
}
} else { //update existing annotation
if ($notetype == "face") { //this is a face
$updatedAnnotation = ORM::factory("items_face")
->where("id", "=", $noteid)
->find();
if ($tag_data == -1) { //needs conversion to note
if ($str_face_title == "") {
message::error(t("Please select a Tag or specify a Title."));
url::redirect($redir_uri);
return;
}
//Save note
$newnote = ORM::factory("items_note");
$newnote->item_id = $item_data;
$newnote->x1 = $str_x1;
$newnote->y1 = $str_y1;
$newnote->x2 = $str_x2;
$newnote->y2 = $str_y2;
$newnote->title = $str_face_title;
$newnote->description = $str_face_description;
$newnote->save();
$updatedAnnotation->delete();
} else { //stays a face
$updatedAnnotation->tag_id = $tag_data;
$updatedAnnotation->item_id = $item_data;
$updatedAnnotation->x1 = $str_x1;
$updatedAnnotation->y1 = $str_y1;
$updatedAnnotation->x2 = $str_x2;
$updatedAnnotation->y2 = $str_y2;
$updatedAnnotation->description = $str_face_description;
$updatedAnnotation->save();
}
} else { //this is a note
$updatedAnnotation = ORM::factory("items_note")
->where("id", "=", $noteid)
->find();
if ($tag_data == -1) { //stays a note
if ($str_face_title == "") {
message::error(t("Please select a Tag or specify a Title."));
url::redirect($redir_uri);
return;
}
$updatedAnnotation->item_id = $item_data;
$updatedAnnotation->x1 = $str_x1;
$updatedAnnotation->y1 = $str_y1;
$updatedAnnotation->x2 = $str_x2;
$updatedAnnotation->y2 = $str_y2;
$updatedAnnotation->title = $str_face_title;
$updatedAnnotation->description = $str_face_description;
$updatedAnnotation->save();
} else { //needs conversion to a face
$newface = ORM::factory("items_face");
$newface->tag_id = $tag_data;
$newface->item_id = $item_data;
$newface->x1 = $str_x1;
$newface->y1 = $str_y1;
$newface->x2 = $str_x2;
$newface->y2 = $str_y2;
$newface->description = $str_face_description;
$newface->save();
$updatedAnnotation->delete();
}
}
}
message::success(t("Annotation saved."));
url::redirect($redir_uri);
@ -162,20 +138,81 @@ class photoannotation_Controller extends Controller {
$notetype = $_POST["notetype"];
$redir_uri = url::abs_site("{$item->type}s/{$item->id}");
if ($noteid == "" || $notetype == "") {
if ($noteid == "") {
message::error(t("Please select a tag or note to delete."));
url::redirect($redir_uri);
return;
}
if ($notetype == "face") {
db::build()->delete("items_faces")->where("id", "=", $noteid)->execute();
message::success(t("Annotation deleted."));
} elseif ($notetype == "note") {
db::build()->delete("items_notes")->where("id", "=", $noteid)->execute();
message::success(t("Annotation deleted."));
} else {
message::error(t("Please select a tag or note to delete."));
switch ($notetype) {
case "user":
db::build()->delete("items_users")->where("id", "=", $noteid)->execute();
break;
case "face":
db::build()->delete("items_faces")->where("id", "=", $noteid)->execute();
break;
case "note":
db::build()->delete("items_notes")->where("id", "=", $noteid)->execute();
break;
default:
message::error(t("Please select a tag or note to delete."));
url::redirect($redir_uri);
return;
}
message::success(t("Annotation deleted."));
url::redirect($redir_uri);
}
}
private function _saveuser($user_id, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description, $annotate_id = "") {
if ($annotate_id == "") {
$item_user = ORM::factory("items_user");
} else {
$item_user = ORM::factory("items_user")
->where("id", "=", $annotate_id)
->find();
}
$item_user->user_id = $user_id;
$item_user->item_id = $item_id;
$item_user->x1 = $str_x1;
$item_user->y1 = $str_y1;
$item_user->x2 = $str_x2;
$item_user->y2 = $str_y2;
$item_user->description = $description;
$item_user->save();
}
private function _saveface($tag_id, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description, $annotate_id = "") {
if ($annotate_id == "") {
$item_face = ORM::factory("items_face");
} else {
$item_face = ORM::factory("items_face")
->where("id", "=", $annotate_id)
->find();
}
$item_face->tag_id = $tag_id;
$item_face->item_id = $item_id;
$item_face->x1 = $str_x1;
$item_face->y1 = $str_y1;
$item_face->x2 = $str_x2;
$item_face->y2 = $str_y2;
$item_face->description = $description;
$item_face->save();
}
private function _savenote($item_title, $item_id, $str_x1, $str_y1, $str_x2, $str_y2, $description, $annotate_id = "") {
if ($annotate_id == "") {
$item_note = ORM::factory("items_note");
} else {
$item_note = ORM::factory("items_note")
->where("id", "=", $annotate_id)
->find();
}
$item_note->item_id = $item_id;
$item_note->x1 = $str_x1;
$item_note->y1 = $str_y1;
$item_note->x2 = $str_x2;
$item_note->y2 = $str_y2;
$item_note->title = $item_title;
$item_note->description = $description;
$item_note->save();
}
}

View File

@ -0,0 +1,93 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 User_Profile_Controller extends Controller {
public function show($id) {
// If we get here, then we should have a user id other than guest.
$user = identity::lookup_user($id);
if (!$user) {
throw new Kohana_404_Exception();
}
$v = new Theme_View("page.html", "photoannotationuserprofile", "dynamic");
$item_users = ORM::factory("items_user")->where("user_id", "=", $id)->find_all();
$children_count = count($item_users);
foreach ($item_users as $item_user) {
$item_thumb = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("id", ">=", $item_user->item_id)
->find();
$item_thumbs[] = $item_thumb;
}
$page_size = module::get_var("gallery", "page_size", 9);
$page = (int) Input::instance()->get("page", "1");
$offset = ($page-1) * $page_size;
$max_pages = max(ceil($children_count / $page_size), 1);
// Make sure that the page references a valid offset
if ($page < 1) {
url::redirect($album->abs_url());
} else if ($page > $max_pages) {
url::redirect($album->abs_url("page=$max_pages"));
}
$v->set_global("page", $page);
$v->set_global("max_pages", $max_pages);
$v->set_global("page_size", $page_size);
$v->set_global("userid", $id);
$v->set_global("children", array_slice($item_thumbs, $offset, $page_size));
$v->set_global("children_count", $children_count);
$v->content = new View("photoannotation_user_profile.html");
$v->content->user = $user;
$v->content->contactable =
!$user->guest && $user->id != identity::active_user()->id && $user->email;
$v->content->editable =
identity::is_writable() && !$user->guest && $user->id == identity::active_user()->id;
$event_data = (object)array("user" => $user, "content" => array());
module::event("show_user_profile", $event_data);
$v->content->info_parts = $event_data->content;
$v->content = new View("dynamic.html");
print $v;
}
public function contact($id) {
$user = identity::lookup_user($id);
print user_profile::get_contact_form($user);
}
public function send($id) {
access::verify_csrf();
$user = identity::lookup_user($id);
$form = user_profile::get_contact_form($user);
if ($form->validate()) {
Sendmail::factory()
->to($user->email)
->subject(html::clean($form->message->subject->value))
->header("Mime-Version", "1.0")
->header("Content-type", "text/html; charset=UTF-8")
->reply_to($form->message->reply_to->value)
->message(html::purify($form->message->message->value))
->send();
message::success(t("Sent message to %user_name", array("user_name" => $user->display_name())));
json::reply(array("result" => "success"));
} else {
json::reply(array("result" => "error", "html" => (string)$form));
}
}
}

View File

@ -45,7 +45,7 @@
#image-annotate-edit-form {
background: #FFFFFF none repeat scroll 0 0;
border: 1px solid #000000;
height: 230px;
height: 300px;
padding: 7px;
position: absolute;
width: 250px;

View File

@ -75,6 +75,16 @@ class photoannotation_event_Core {
db::build()->delete("items_notes")->where("item_id", "=", $item->id)->execute();
}
}
static function user_deleted($old) {
// Check for and delete existing Annotations linked to that user.
$existingFaces = ORM::factory("items_user")
->where("user_id", "=", $old->id)
->find_all();
if (count($existingFaces) > 0) {
db::build()->delete("items_users")->where("user_id", "=", $old->id)->execute();
}
}
static function admin_menu($menu, $theme) {
$menu->get("settings_menu")

View File

@ -44,15 +44,42 @@ class photoannotation_installer {
`description` varchar(2048) default NULL,
PRIMARY KEY (`id`))
DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {items_users} (
`id` int(9) NOT NULL auto_increment,
`user_id` int(9) NOT NULL,
`item_id` int(9) NOT NULL,
`x1` int(9) NOT NULL,
`y1` int(9) NOT NULL,
`x2` int(9) NOT NULL,
`y2` int(9) NOT NULL,
`description` varchar(2048) default NULL,
PRIMARY KEY (`id`))
DEFAULT CHARSET=utf8;");
// Set the module's version number.
module::set_version("photoannotation", 2);
module::set_version("photoannotation", 3);
}
static function upgrade($version) {
if ($version == 1) {
module::set_version("photoannotation", $version = 2);
}
if ($version == 2) {
$db = Database::instance();
$db->query("CREATE TABLE IF NOT EXISTS {items_users} (
`id` int(9) NOT NULL auto_increment,
`user_id` int(9) NOT NULL,
`item_id` int(9) NOT NULL,
`x1` int(9) NOT NULL,
`y1` int(9) NOT NULL,
`x2` int(9) NOT NULL,
`y2` int(9) NOT NULL,
`description` varchar(2048) default NULL,
PRIMARY KEY (`id`))
DEFAULT CHARSET=utf8;");
module::set_version("photoannotation", $version = 3);
}
}
static function deactivate() {
@ -66,6 +93,7 @@ class photoannotation_installer {
$db = Database::instance();
$db->query("DROP TABLE IF EXISTS {items_faces};");
$db->query("DROP TABLE IF EXISTS {items_notes};");
$db->query("DROP TABLE IF EXISTS {items_users};");
module::delete("photoannotation");
}
}

View File

@ -25,9 +25,16 @@ class photoannotation_theme_Core {
}
}
static function photo_bottom($theme) {
static function resize_bottom($theme) {
if ($theme->page_subtype == "photo") {
return new View("photoannotation_highlight_block.html");
}
}
static function dynamic_top($theme) {
return new View("photoannotation_user_profile.html");
if ($theme->page_type == "photoannotationuserprofile") {
return new View("photoannotation_user_profile.html");
}
}
}

View File

@ -25,6 +25,7 @@
this.csrf = opts.csrf;
this.cssaclass = opts.cssaclass;
this.rtlsupport = opts.rtlsupport;
this.users = opts.users
// Add the canvas
this.canvas = $('<div class="image-annotate-canvas g-thumbnail"><div class="image-annotate-view"></div><div class="image-annotate-edit"><div class="image-annotate-edit-area"></div></div></div>');
@ -60,14 +61,14 @@
if (this.useAjax) {
$.fn.annotateImage.ajaxLoad(this);
} else {
$.fn.annotateImage.load(this, this.labels, this.editable, this.csrf, this.deleteUrl, this.tags, this.saveUrl, this.cssaclass, this.rtlsupport);
$.fn.annotateImage.load(this, this.labels, this.editable, this.csrf, this.deleteUrl, this.tags, this.saveUrl, this.cssaclass, this.rtlsupport, this.users);
}
// Add the "Add a note" button
if ($('#g-photoannotation-link').length != 0) {
this.button = $('#g-photoannotation-link');
this.button.click(function() {
$.fn.annotateImage.add(image, opts.tags, opts.labels, opts.saveUrl, opts.csrf, opts.rtlsupport);
$.fn.annotateImage.add(image, opts.tags, opts.labels, opts.saveUrl, opts.csrf, opts.rtlsupport, opts.users);
});
//this.canvas.after(this.button);
}
@ -112,13 +113,13 @@
});
};
$.fn.annotateImage.load = function(image, labels, editable, csrf, deleteUrl, tags, saveUrl, cssaclass, rtlsupport) {
$.fn.annotateImage.load = function(image, labels, editable, csrf, deleteUrl, tags, saveUrl, cssaclass, rtlsupport, users) {
/// <summary>
/// Loads the annotations from the notes property passed in on the
/// options object.
/// </summary>
for (var i = 0; i < image.notes.length; i++) {
image.notes[image.notes[i]] = new $.fn.annotateView(image, image.notes[i], tags, labels, editable, csrf, deleteUrl, saveUrl, cssaclass, rtlsupport);
image.notes[image.notes[i]] = new $.fn.annotateView(image, image.notes[i], tags, labels, editable, csrf, deleteUrl, saveUrl, cssaclass, rtlsupport, users);
}
};
@ -131,7 +132,7 @@
return now.getTime();
};
$.fn.annotateImage.add = function(image, tags, labels, saveUrl, csrf, rtlsupport) {
$.fn.annotateImage.add = function(image, tags, labels, saveUrl, csrf, rtlsupport, users) {
/// <summary>
/// Adds a note to the image.
/// </summary>
@ -139,18 +140,18 @@
image.mode = 'edit';
// Create/prepare the editable note elements
var editable = new $.fn.annotateEdit(image, null, tags, labels, saveUrl, csrf, rtlsupport);
var editable = new $.fn.annotateEdit(image, null, tags, labels, saveUrl, csrf, rtlsupport, users);
$.fn.annotateImage.createSaveButton(editable, image, null, rtlsupport);
$.fn.annotateImage.createCancelButton(editable, image, rtlsupport);
$.fn.annotateImage.createSaveButton(editable, image, null, rtlsupport, labels);
$.fn.annotateImage.createCancelButton(editable, image, rtlsupport, labels);
}
};
$.fn.annotateImage.createSaveButton = function(editable, image, note, rtlsupport) {
$.fn.annotateImage.createSaveButton = function(editable, image, note, rtlsupport, labels) {
/// <summary>
/// Creates a Save button on the editable note.
/// </summary>
var ok = $('<a class="image-annotate-edit-ok g-button ui-corner-all ui-icon-left ui-state-default ' + rtlsupport + '">OK</a>');
var ok = $('<a class="image-annotate-edit-ok g-button ui-corner-all ui-icon-left ui-state-default ' + rtlsupport + '">' + labels[8] + '</a>');
ok.click(function() {
var form = $('#image-annotate-edit-form form');
@ -165,11 +166,11 @@
editable.form.append(ok);
};
$.fn.annotateImage.createCancelButton = function(editable, image, rtlsupport) {
$.fn.annotateImage.createCancelButton = function(editable, image, rtlsupport, labels) {
/// <summary>
/// Creates a Cancel button on the editable note.
/// </summary>
var cancel = $('<a class="image-annotate-edit-close g-button ui-corner-all ui-icon-left ui-state-default ' + rtlsupport + '">Cancel</a>');
var cancel = $('<a class="image-annotate-edit-close g-button ui-corner-all ui-icon-left ui-state-default ' + rtlsupport + '">' + labels[9] + '</a>');
cancel.click(function() {
editable.destroy();
image.mode = 'view';
@ -195,7 +196,7 @@
return '&lt;input type="hidden" name="' + name + '" value="' + value + '" /&gt;<br />';
};
$.fn.annotateEdit = function(image, note, tags, labels, saveUrl, csrf, rtlsupport) {
$.fn.annotateEdit = function(image, note, tags, labels, saveUrl, csrf, rtlsupport, users) {
/// <summary>
/// Defines an editable annotation area.
/// </summary>
@ -231,16 +232,31 @@
// Add the note (which we'll load with the form afterwards)
var selectedtag = "";
var notetitle = "";
var username = "";
var selecteduser = "";
if (this.note.notetype == "face") {
selectedtag = this.note.text;
selecteduser = " selected=\"selected\"";
} else if (this.note.notetype == "user") {
username = this.note.text;
} else {
notetitle = this.note.text;
selecteduser = " selected=\"selected\"";
}
var form = $('<div id="image-annotate-edit-form" class="' + rtlsupport + '"><form id="photoannotation-form" action="' + saveUrl + '" method="post"><input type="hidden" name="csrf" value="' + csrf + '" /><input type="hidden" name="noteid" value="' + this.note.noteid + '" /><input type="hidden" name="notetype" value="' + this.note.notetype + '" />' + labels[0] + '<input id="image-annotate-tag-text" type="text" name="tagsList" value="' + selectedtag + '" />' + '<strong>' + labels[4] + '</strong><br />' + labels[1] + '<textarea id="image-annotate-text" name="text" rows="3" cols="30">' + notetitle + '</textarea>' + labels[2] + '<textarea id="image-annotate-desc" name="desc" rows="3" cols="30">' + this.note.description + '</textarea></form></div>');
var userdropdown = '<select id="photoannotation-user-list" class="dropdown" style="width: 240px;" name="userlist"><option value="-1"' + selecteduser + '>' + labels[11] + '</option>';
for (var user in users)
{
var userval = users[user];
selecteduser = "";
if (userval.name == this.note.text && this.note.notetype == "user") {
selecteduser = " selected=\"selected\"";
}
userdropdown += '<option value="' + userval.id + '"' + selecteduser + '>' + userval.name + '</option>';
}
userdropdown += '</select>';
var form = $('<div id="image-annotate-edit-form" class="' + rtlsupport + '"><form id="photoannotation-form" action="' + saveUrl + '" method="post"><input type="hidden" name="csrf" value="' + csrf + '" /><input type="hidden" name="noteid" value="' + this.note.noteid + '" /><input type="hidden" name="notetype" value="' + this.note.notetype + '" />' + labels[10] + userdropdown + '<hr /><strong>' + labels[4] + '</strong><br />' + labels[0] + '<input id="image-annotate-tag-text" type="text" name="tagsList" style="width: 240px;" value="' + selectedtag + '" />' + '<hr /><strong>' + labels[4] + '</strong><br />' + labels[1] + '<input id="image-annotate-text" type="text" name="text" style="width: 240px;" value="' + notetitle + '" /><hr />' + labels[2] + '<textarea id="image-annotate-desc" name="desc" rows="3" style="width: 240px;">' + this.note.description + '</textarea></form></div>');
this.form = form;
$('body').append(this.form);
$("#photoannotation-form").ready(function() {
var url = tags;
$("input#image-annotate-tag-text").autocomplete(
@ -251,23 +267,32 @@
}
);
});
$("input#image-annotate-tag-text").keyup(function() {
$("input#image-annotate-tag-text").change(function() {
if ($("input#image-annotate-tag-text").val() != "") {
$("textarea#image-annotate-text").html("");
$("textarea#image-annotate-text").val("");
$("textarea#image-annotate-text").text("");
$("input#image-annotate-text").html("");
$("input#image-annotate-text").val("");
$("input#image-annotate-text").text("");
$("select#photoannotation-user-list").val('-1');
}
});
$("textarea#image-annotate-text").keyup(function() {
if ($("textarea#image-annotate-text").val() != "") {
$("input#image-annotate-text").keyup(function() {
if ($("input#image-annotate-text").val() != "") {
$("input#image-annotate-tag-text").html("");
$("input#image-annotate-tag-text").val("");
$("input#image-annotate-tag-text").text("");
$("select#photoannotation-user-list").val('-1');
}
});
$("select#photoannotation-user-list").keyup(function() {
if ($("select#photoannotation-user-list").val() != "-1") {
$("input#image-annotate-tag-text").html("");
$("input#image-annotate-tag-text").val("");
$("input#image-annotate-tag-text").text("");
$("input#image-annotate-text").html("");
$("input#image-annotate-text").val("");
$("input#image-annotate-text").text("");
}
});
this.form.css('left', this.area.offset().left + 'px');
this.form.css('top', (parseInt(this.area.offset().top) + parseInt(this.area.height()) + 7) + 'px');
@ -313,7 +338,7 @@
this.form.remove();
}
$.fn.annotateView = function(image, note, tags, labels, editable, csrf, deleteUrl, saveUrl, cssaclass, rtlsupport) {
$.fn.annotateView = function(image, note, tags, labels, editable, csrf, deleteUrl, saveUrl, cssaclass, rtlsupport, users) {
/// <summary>
/// Defines a annotation area.
/// </summary>
@ -322,7 +347,7 @@
this.note = note;
// Add the area
this.area = $('<div class="image-annotate-area' + (this.note.editable ? ' image-annotate-area-editable' : '') + '"><div></div></div>');
this.area = $('<div id="photoannotation-area-' + this.note.notetype + "-" + this.note.noteid + '" class="image-annotate-area' + (this.note.editable ? ' image-annotate-area-editable' : '') + '"><div></div></div>');
image.canvas.children('.image-annotate-view').prepend(this.area);
if (editable) {
@ -360,7 +385,7 @@
alink.unbind();
alink.attr ('href', '#');
alink.removeAttr ('rel');
form.edit(tags, labels, saveUrl, csrf, rtlsupport);
form.edit(tags, labels, saveUrl, csrf, rtlsupport, users);
})
this.delarea.hide();
this.editarea.hide();
@ -394,7 +419,21 @@
annotation.editarea.hide();
}
});
var legendspan = "#photoannotation-legend-" + this.note.notetype + "-" + this.note.noteid;
if ($(legendspan).length > 0) {
$(legendspan).hover(function() {
var legendsarea = "#photoannotation-area-" + note.notetype + "-" + note.noteid;
$(legendsarea).children('.image-annotate-view').show();
$(".image-annotate-view").show();
$(legendsarea).show();
annotation.show();
}, function() {
var legendsarea = "#photoannotation-area-" + note.notetype + "-" + note.noteid;
annotation.hide();
$(legendsarea).children('.image-annotate-view').hide();
$(".image-annotate-view").hide();
});
}
if (editable) {
this.delarea.hover(function() {
annotation.delarea.show();
@ -480,7 +519,7 @@
this.form.remove();
}
$.fn.annotateView.prototype.edit = function(tags, labels, saveUrl, csrf, rtlsupport) {
$.fn.annotateView.prototype.edit = function(tags, labels, saveUrl, csrf, rtlsupport, users) {
/// <summary>
/// Edits the annotation.
/// </summary>
@ -489,9 +528,9 @@
var annotation = this;
// Create/prepare the editable note elements
var editable = new $.fn.annotateEdit(this.image, this.note, tags, labels, saveUrl, csrf, rtlsupport);
$.fn.annotateImage.createSaveButton(editable, this.image, annotation, rtlsupport);
$.fn.annotateImage.createCancelButton(editable, this.image, rtlsupport);
var editable = new $.fn.annotateEdit(this.image, this.note, tags, labels, saveUrl, csrf, rtlsupport, users);
$.fn.annotateImage.createSaveButton(editable, this.image, annotation, rtlsupport, labels);
$.fn.annotateImage.createCancelButton(editable, this.image, rtlsupport, labels);
}
};

View File

@ -0,0 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 Items_User_Model extends ORM {
}

View File

@ -1,3 +1,3 @@
name = "Photo Annotation"
description = "Allows you to assign tags and notes to areas on your photos. Fully compatible with TagFaces module by rWatcher but you cannot run both modules at the same time."
version = 2
description = "Allows you to assign tags and notes to areas on your photos. This module is partially compatible with the TagFaces module by rWatcher. This means that notes and faces that you create in either one will be shown and are editable by the other module as well. If you added users to an annotation area though they will only be displayed with the Photo Annotation module. You cannot run both modules at the same time."
version = 3

View File

@ -2,9 +2,9 @@
<div id="g-admin-photoannotation">
<h2><?= t("Photo annotation administration") ?></h2>
<h3><?= t("Notes:") ?></h3>
<p><?= t("This module is fully compatible with the <a href=\"http://codex.gallery2.org/Gallery3:Modules:tagfaces\">TagFaces module</a> by rWatcher.<br />
This means that notes and faces that you create in either one will be shown and are editable by the other module as well.<br />
However since both modules do the same you cannot have both active at the same time.<br /><br />
<p><?= t("This module is partially compatible with the <a href=\"http://codex.gallery2.org/Gallery3:Modules:tagfaces\">TagFaces module</a> by rWatcher.<br />
This means that notes and faces that you create in either one will be shown and are editable by the other module as well. If you added users to an annotation area though they will only be displayed with the Photo Annotation module.<br />
You cannot have both active at the same time.<br /><br />
If you decide to show annotations below the photo but they are displayed below the comments section (or any other data),
please download and install the <a href=\"http://codex.gallery2.org/Gallery3:Modules:moduleorder\">Module order module</a>.") ?></p>
<?= $form ?>

View File

@ -1,12 +1,19 @@
<?php defined("SYSPATH") or die("No direct script access.");
// Check and see if the current photo has any faces or notes associated with it.
$existingUsers = ORM::factory("items_user")
->where("item_id", "=", $item->id)
->find_all();
$existingFaces = ORM::factory("items_face")
->where("item_id", "=", $item->id)
->find_all();
$existingNotes = ORM::factory("items_note")
->where("item_id", "=", $item->id)
->find_all();
$users = ORM::factory("user")->order_by("name", "ASC")->find_all();
$fullname = module::get_var("photoannotation", "fullname", false);
$showusers = module::get_var("photoannotation", "showusers", false);
$showfaces = module::get_var("photoannotation", "showfaces", false);
$shownotes = module::get_var("photoannotation", "shownotes", false);
if (locales::is_rtl()) {
$rtl_support = "image-annotate-rtl";
} else {
@ -25,12 +32,37 @@
}
// If it does, then insert some javascript and display an image map
// to show where the faces are at.
if ((count($existingFaces) > 0) || (count($existingNotes) > 0)) {
if ((count($existingFaces) > 0) || (count($existingNotes) > 0) || (count($existingUsers) > 0)) {
$jscode = "notes: [ ";
foreach ($existingUsers as $oneUser) {
$oneTag = ORM::factory("user", $oneUser->user_id);
if ($fullname && ($oneTag->full_name != "")) {
$user_text = $oneTag->full_name;
} else {
$user_text = $oneTag->name;
}
if ($showusers) {
$legend_users .= "<span id=\"photoannotation-legend-user-". $oneUser->id . "\"><a href=\"". user_profile::url($oneUser->user_id) ."\">". html::clean($user_text) ."</a></span>, ";
}
$jscode .= "{ \"top\": ". $oneUser->y1 .",\n";
$jscode .= "\"left\": ". $oneUser->x1 .",\n";
$jscode .= "\"width\": ". ($oneUser->x2 - $oneUser->x1) .",\n";
$jscode .= "\"height\": ". ($oneUser->y2 - $oneUser->y1) .",\n";
$jscode .= "\"text\": \"". html::clean($user_text) ."\",\n";
$jscode .= "\"description\": \"". html::clean($oneUser->description) ."\",\n";
$jscode .= "\"noteid\": ". $oneUser->id .",\n";
$jscode .= "\"notetype\": \"user\",\n";
$jscode .= "\"editable\": true,\n";
$jscode .= "\"url\": \"". user_profile::url($oneUser->user_id) ."\" },\n";
}
if ($legend_users != "") {
$legend_users = trim($legend_users, ", ");
$legend_users = t("Users on this photo: ") . $legend_users;
}
foreach ($existingFaces as $oneFace) {
$oneTag = ORM::factory("tag", $oneFace->tag_id);
if (module::get_var("photoannotation", "showfaces", false)) {
$legend_faces .= "<a href=\"". $oneTag->url() ."\">". html::clean($oneTag->name) ."</a>, ";
if ($showfaces) {
$legend_faces .= "<span id=\"photoannotation-legend-face-". $oneFace->id . "\"><a href=\"". $oneTag->url() ."\">". html::clean($oneTag->name) ."</a></span>, ";
}
$jscode .= "{ \"top\": ". $oneFace->y1 .",\n";
$jscode .= "\"left\": ". $oneFace->x1 .",\n";
@ -48,8 +80,8 @@
$legend_faces = t("Faces on this photo: ") . $legend_faces;
}
foreach ($existingNotes as $oneNote) {
if (module::get_var("photoannotation", "shownotes", false)) {
$legend_notes .= html::clean($oneNote->title) .", ";
if ($shownotes) {
$legend_notes .= "<span id=\"photoannotation-legend-note-". $oneNote->id . "\">". html::clean($oneNote->title) ."</span>, ";
}
$jscode .= "{ \"top\": ". $oneNote->y1 .",\n";
$jscode .= "\"left\": ". $oneNote->x1 .",\n";
@ -69,15 +101,23 @@
$legend_notes = t("Notes on this photo: ") . $legend_notes;
}
}
$legend_display = $legend_faces;
if ($legend_display == "") {
$legend_display = $legend_notes;
} else {
if ($legend_notes != "") {
$legend_display = $legend_display ."<br />". $legend_notes;
}
$legend_display = "";
if ($legend_users != "" || $legend_faces != "" || $legend_notes != "") {
$legend_display = $legend_users . "<br />" . $legend_faces . "<br />" . $legend_notes;
$legend_display = str_replace("<br /><br />", "<br />", $legend_display);
}
$labels_arraystring = "labels: [ '". t("Tag:") ."','". t("Note Title:") ."','". t("Description (optional):") ."','". t("Are you sure you want to delete this annotation?") ."','". t("or") ."','". t("Yes") ."','". t("No") ."','". t("Confirm deletion") ."' ],";
$users_arraystring = "users: [ ";
foreach ($users as $user) {
if ($fullname && ($user->full_name != "")) {
$user_text = $user->full_name;
} else {
$user_text = $user->name;
}
$users_arraystring .= "{'name':'". html::clean($user_text) ."','id':'". $user->id ."'},";
}
$users_arraystring = trim($users_arraystring, ",");
$users_arraystring .= " ],";
$labels_arraystring = "labels: [ '". t("Tag:") ."','". t("Note Title:") ."','". t("Description (optional):") ."','". t("Are you sure you want to delete this annotation?") ."','". t("or") ."','". t("Yes") ."','". t("No") ."','". t("Confirm deletion") ."','". t("Save") ."','". t("Cancel") ."','". t("User") ."','". t("No user selected") ."' ],";
?>
<script type="text/javascript">
$(document).ready(function() {
@ -92,6 +132,7 @@
tags: '<?= url::site("tags/autocomplete") ?>',
<?= $labels_arraystring ?>
<?= $jscode ?>
<?= $users_arraystring ?>
rtlsupport: '<?= $rtl_support ?>',
useAjax: false,
cssaclass: '<?= $css_a_class ?>',

View File

@ -0,0 +1,47 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<script type="text/javascript">
$(document).ready(function() {
$("#g-profile-return").click(function(event) {
history.go(-1);
return false;
})
});
</script>
<div id="g-user-profile">
<div class="ui-helper-clearfix">
<a id="g-profile-return" class="g-button g-right ui-state-default ui-corner-all" href="#">
<?= t("Return") ?>
</a>
<? if ($editable): ?>
<a class="g-button g-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("users/form_change_email/{$user->id}") ?>">
<?= t("Change email") ?>
</a>
<a class="g-button g-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("users/form_change_password/{$user->id}") ?>">
<?= t("Change password") ?>
</a>
<a class="g-button g-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("form/edit/users/{$user->id}") ?>">
<?= t("Edit") ?>
</a>
<? endif ?>
<? if ($contactable): ?>
<a class="g-button g-right ui-state-default ui-corner-all g-dialog-link"
href="<?= url::site("user_profile/contact/{$user->id}") ?>">
<?= t("Contact") ?>
</a>
<? endif ?>
</div>
<h1>
<img src="<?= $user->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>"
alt="<?= html::clean_attribute($user->display_name()) ?>"
class="g-avatar g-left" width="40" height="40" />
<?= t("User profile: %name", array("name" => $user->display_name())) ?>
</h1>
<? foreach ($info_parts as $info): ?>
<div class="g-block">
<h2><?= html::purify($info->title) ?></h2>
<div class="g-block-content">
<?= $info->view ?>
</div>
</div>
<? endforeach ?>
</div>

View File

@ -0,0 +1,9 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<table>
<? foreach ($user_profile_data as $label => $value): ?>
<tr>
<th><?= html::clean($label) ?></th>
<td><?= html::purify($value) ?></td>
</tr>
<? endforeach ?>
</table>

View File

@ -11,7 +11,7 @@
<?= t("Admin dashboard") ?>
<? endif ?>
</title>
<link rel="shortcut icon" href="<?= url::file("lib/images/favicon.ico") ?>" type="image/x-icon" />
<link rel="shortcut icon" href="<?= url::file(module::get_var("gallery", "favicon_url")) ?>" type="image/x-icon" />
<?= $theme->css("yui/reset-fonts-grids.css") ?>
<?= $theme->css("themeroller/ui.base.css") ?>
@ -77,9 +77,11 @@
</div>
<div id="g-footer" class="g-inline ui-helper-clearfix">
<?= $theme->admin_footer() ?>
<div>
<? if (module::get_var("gallery", "show_credits")): ?>
<ul id="g-credits" class="g-inline">
<?= $theme->admin_credits() ?>
</div>
</ul>
<? endif ?>
</div>
</div>
<?= $theme->admin_page_bottom() ?>

View File

@ -16,7 +16,9 @@
<li id="g-item-id-<?= $child->id ?>" class="g-item <?= $item_class ?>">
<?= $theme->thumb_top($child) ?>
<a href="<?= $child->url() ?>">
<? if ($child->has_thumb()): ?>
<?= $child->thumb_img(array("class" => "g-thumbnail")) ?>
<? endif ?>
</a>
<?= $theme->thumb_bottom($child) ?>
<?= $theme->context_menu($child, "#g-item-id-{$child->id} .g-thumbnail") ?>

View File

@ -23,7 +23,7 @@
<? endif ?>
<? endif ?>
</title>
<link rel="shortcut icon" href="<?= url::file("lib/images/favicon.ico") ?>" type="image/x-icon" />
<link rel="shortcut icon" href="<?= url::file(module::get_var("gallery", "favicon_url")) ?>" type="image/x-icon" />
<?= $theme->css("yui/reset-fonts-grids.css") ?>
<?= $theme->css("superfish/css/superfish.css") ?>
<?= $theme->css("themeroller/ui.base.css") ?>
@ -101,18 +101,23 @@
<? $i = 0 ?>
<? foreach ($parents as $parent): ?>
<li<? if ($i == 0) print " class=\"g-first\"" ?>>
<!-- Adding ?show=<id> causes Gallery3 to display the page
containing that photo. For now, we just do it for
the immediate parent so that when you go back up a
level you're on the right page. -->
<a href="<?= $parent->url($parent == $theme->item()->parent() ?
<? // Adding ?show=<id> causes Gallery3 to display the page
// containing that photo. For now, we just do it for
// the immediate parent so that when you go back up a
// level you're on the right page. ?>
<a href="<?= $parent->url($parent->id == $theme->item()->parent_id ?
"show={$theme->item()->id}" : null) ?>">
<?= html::purify($parent->title) ?>
<? // limit the title length to something reasonable (defaults to 15) ?>
<?= html::purify(text::limit_chars($parent->title,
module::get_var("gallery", "visible_title_length"))) ?>
</a>
</li>
<? $i++ ?>
<? endforeach ?>
<li class="g-active<? if ($i == 0) print " g-first" ?>"><?= html::purify($theme->item()->title) ?></li>
<li class="g-active<? if ($i == 0) print " g-first" ?>">
<?= html::purify(text::limit_chars($theme->item()->title,
module::get_var("gallery", "visible_title_length"))) ?>
</li>
</ul>
<? endif ?>
</div>