Monotone-Parent: 1b073e285785f32b4c27e867a0e0d363fdc74264

Monotone-Revision: 217d2de82145e1b73b967f969ccb9467d0680dcb

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2010-11-01T19:32:19
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2010-11-01 19:32:19 +00:00
parent dadaa9fda3
commit 2b79a77c36
8 changed files with 275 additions and 6 deletions

View File

@@ -1,5 +1,17 @@
2010-11-01 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/WebServerResources/ContactsUI.js: (resetCategoriesMenu)
(onCategoriesMenuPrepareVisibility, onCategoriesMenuItemClick)
(setCategoryOnNode, unsetCategoryOnNode): new methods designed to
handle the handling of categories directly from the contacts list.
* SoObjects/Contacts/SOGoContactGCSFolder.m (+initialize): we now
return the "c_categories" field too.
* UI/Contacts/UIxContactActions.m: new class module implementing
actions on contacts.
(-setCategoryAction, -unsetCategoryAction): new actions.
* UI/WebServerResources/generic.js (triggerAjaxRequest): invoke
the request callback only when set on the http object.

View File

@@ -62,6 +62,7 @@ static NSArray *folderListingFields = nil;
@"c_cn", @"c_givenname", @"c_sn",
@"c_screenname", @"c_o",
@"c_mail", @"c_telephonenumber",
@"c_categories",
@"c_component", nil];
}

View File

@@ -15,6 +15,7 @@ ContactsUI_OBJC_FILES = \
\
ContactsUIProduct.m \
UIxContactsFilterPanel.m \
UIxContactActions.m \
UIxContactView.m \
UIxContactEditor.m \
UIxListView.m \

View File

@@ -0,0 +1,131 @@
/* UIxContactActions.m - this file is part of SOGo
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file 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, or (at your option)
* any later version.
*
* This file 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/WODirectAction.h>
#import <NGObjWeb/WORequest.h>
#import <NGCards/NGVCard.h>
#import <Contacts/SOGoContactGCSEntry.h>
#import <Common/WODirectAction+SOGo.h>
@interface NGVCard (SOGoActionCategory)
- (BOOL) addOrRemove: (BOOL) set
category: (NSString *) newCategory;
@end
@implementation NGVCard (SOGoActionCategory)
- (BOOL) addOrRemove: (BOOL) set
category: (NSString *) category
{
NSMutableArray *categories;
BOOL modified;
NSUInteger idx;
modified = NO;
categories = [[self categories] mutableCopy];
[categories autorelease];
if (set)
{
if (![categories containsObject: category])
{
[categories addObject: category];
modified = YES;
}
}
else
{
idx = [categories indexOfObject: category];
if (idx != NSNotFound)
{
[categories removeObjectAtIndex: idx];
modified = YES;
}
}
if (modified)
[self setCategories: categories];
return modified;
}
@end
@interface UIxContactActions : WODirectAction
- (WOResponse *) setCategoryAction;
- (WOResponse *) unsetCategoryAction;
@end
@implementation UIxContactActions
- (WOResponse *) _setOrUnsetCategoryAction: (BOOL) set
{
SOGoContactGCSEntry *contact;
NSString *category;
WORequest *rq;
WOResponse *response;
NGVCard *card;
rq = [context request];
category = [rq formValueForKey: @"category"];
if ([category length] > 0)
{
contact = [self clientObject];
if (![contact isNew])
{
card = [contact vCard];
if ([card addOrRemove: set category: category])
[contact save];
response = [self responseWith204];
}
else
response = [self responseWithStatus: 404
andString: @"Contact does not exist"];
}
else
response = [self responseWithStatus: 403
andString: @"Missing 'category' parameter"];
return response;
}
- (WOResponse *) setCategoryAction
{
return [self _setOrUnsetCategoryAction: YES];
}
- (WOResponse *) unsetCategoryAction
{
return [self _setOrUnsetCategoryAction: NO];
}
@end

View File

@@ -184,6 +184,16 @@
pageName = "UIxContactEditor";
actionName = "write";
};
setCategory = {
protectedBy = "Change Images And Files";
actionClass = "UIxContactActions";
actionName = "setCategory";
};
unsetCategory = {
protectedBy = "Change Images And Files";
actionClass = "UIxContactActions";
actionName = "unsetCategory";
};
};
};

View File

@@ -7,6 +7,7 @@
xmlns:uix="OGo:uix"
xmlns:label="OGo:label"
xmlns:rsrc="OGo:url"
const:userDefaultsKeys="SOGoContactsCategories"
className="UIxPageFrame"
title="name"
var:popup="isPopup">
@@ -72,6 +73,7 @@
<div class="menu" id="contactMenu">
<ul>
<li><var:string label:value="Properties" /></li>
<li><var:string label:value="Categories" /></li>
<li><!-- separator --></li>
<li><var:string label:value="Write" /></li>
<li><var:string label:value="Instant Message" /></li>

View File

@@ -27,6 +27,7 @@
<tbody id="contactsListTbody">
<var:foreach list="contactInfos" item="currentContact">
<tr class="tableview"
var:categories="currentContact.c_categories"
var:id="currentContact.c_name"
var:contactname="currentContact.c_cn">
<td class="displayName"><var:string value="currentContact.c_cn" const:escapeHTML="YES" /></td>

View File

@@ -1078,10 +1078,14 @@ function onContactMenuPrepareVisibility() {
aim: false };
var elements = $(this).down("ul").childElements();
var writeOption = elements[2];
var aimOption = elements[3];
var deleteOption = elements[5];
var moveOption = elements[7];
var categoriesOption = elements[1];
if (selectedFolder.getAttribute("owner") == UserLogin) {
categoriesOption.removeClassName("disabled");
}
else {
categoriesOption.addClassName("disabled");
}
$A(contactRows).each(function(contactRow) {
var cells = contactRow.getElementsByTagName('td');
@@ -1091,15 +1095,20 @@ function onContactMenuPrepareVisibility() {
options.aim |= (aimCell.firstChild != null);
});
var writeOption = elements[3];
if (options.write)
writeOption.removeClassName("disabled");
else
writeOption.addClassName("disabled");
var aimOption = elements[4];
if (options.aim)
aimOption.removeClassName("disabled");
else
aimOption.addClassName("disabled");
var deleteOption = elements[6];
var moveOption = elements[8];
if ($(selectedFolder).hasClassName("remote")) {
// Remote address books are always read-only
deleteOption.addClassName("disabled");
@@ -1120,7 +1129,9 @@ function getMenus() {
onAddressBookRemove, "-",
onAddressBookExport, onAddressBookImport, "-",
onMenuSharing);
menus["contactMenu"] = new Array(onMenuEditContact, "-",
menus["contactMenu"] = new Array(onMenuEditContact,
"categoriesMenu",
"-",
onMenuWriteToContact, onMenuAIMContact,
"-", onMenuDeleteContact, "-",
"moveContactMenu", "copyContactMenu",
@@ -1255,6 +1266,107 @@ function initContacts(event) {
// Default sort options
sorting["attribute"] = "c_cn";
sorting["ascending"] = true;
resetCategoriesMenu();
}
function resetCategoriesMenu() {
var menu = $("categoriesMenu");
if (menu) {
menu.parentNode.removeChild(menu);
}
menu = createElement("div", "categoriesMenu", "menu");
var menuUL = createElement("ul", null, "choiceMenu");
menu.appendChild(menuUL);
if (UserDefaults && UserDefaults["SOGoContactsCategories"]) {
for (var i = 0;
i < UserDefaults["SOGoContactsCategories"].length;
i++) {
var catName = UserDefaults["SOGoContactsCategories"][i];
if (catName.length > 0) {
var menuLI = createElement("li");
var bound = onCategoriesMenuItemClick.bindAsEventListener(menuLI);
menuLI.observe("click", bound);
menuLI.category = catName;
menuLI.appendChild(document.createTextNode(catName));
menuUL.appendChild(menuLI);
}
}
}
menu.prepareVisibility = onCategoriesMenuPrepareVisibility;
var pageContent = $("pageContent");
pageContent.appendChild(menu);
}
function onCategoriesMenuPrepareVisibility() {
var rows = contactsList.getSelectedRows();
if (rows.length > 0) {
var catList = rows[0].getAttribute("categories");
var catsArray;
if (catList && catList.length > 0) {
catsArray = catList.split(",");
}
else {
catsArray = [];
}
var menu = $("categoriesMenu");
var ul = menu.down("ul");
var listElements = ul.select("li");
for (var i = 0; i < listElements.length; i++) {
var li = listElements[i];
if (catsArray.indexOf(li.category) > -1) {
li.addClassName("_chosen");
}
else {
li.removeClassName("_chosen");
}
}
}
}
function onCategoriesMenuItemClick() {
var set = !this.hasClassName("_chosen");
var method = (set ? "setCategory" : "unsetCategory");
var contactsList = $("contactsList");
var rowIds = contactsList.getSelectedRowsId();
if (rowIds.length > 0) {
log("coucou...");
for (var i = 0; i < rowIds.length; i++) {
var url = (URLForFolderID(Contact.currentAddressBook)
+ "/" + rowIds[i] + "/" + method);
url += "?category=" + escape(this.category);
triggerAjaxRequest(url);
if (set) {
setCategoryOnNode($(rowIds[i]), this.category);
}
else {
unsetCategoryOnNode($(rowIds[i]), this.category);
}
}
}
}
function setCategoryOnNode(contactNode, category) {
var catList = contactNode.getAttribute("categories");
var catsArray = catList.split(",");
if (catsArray.indexOf(category) == -1) {
catsArray.push(category);
contactNode.setAttribute("categories", catsArray.join(","));
}
}
function unsetCategoryOnNode(contactNode, category) {
var catList = contactNode.getAttribute("categories");
var catsArray = catList.split(",");
var catIdx = catsArray.indexOf(category);
if (catsArray.indexOf(category) > -1) {
catsArray.splice(catIdx, 1);
contactNode.setAttribute("categories", catsArray.join(","));
}
}
function configureDraggables() {
@@ -1362,7 +1474,6 @@ function dropSelectedContacts (action, toId) {
}
}
function onContactsReload () {
openContactsFolder(Contact.currentAddressBook, true);
}