[rt-commit] [svn] r469 - in rt/branches: . autrijus-3.1 autrijus-3.1/bin autrijus-3.1/etc autrijus-3.1/html autrijus-3.1/html/Admin autrijus-3.1/html/Admin/CustomFields autrijus-3.1/html/Admin/Elements autrijus-3.1/html/Admin/Global autrijus-3.1/html/Admin/Groups autrijus-3.1/html/Admin/Queues autrijus-3.1/html/Admin/Users autrijus-3.1/html/Elements autrijus-3.1/html/NoAuth autrijus-3.1/html/Projects autrijus-3.1/html/Projects/Elements autrijus-3.1/html/Search autrijus-3.1/html/Search/Elements autrijus-3.1/html/Ticket/Attachment autrijus-3.1/html/Ticket/Elements autrijus-3.1/lib/RT autrijus-3.1/lib/RT/Action autrijus-3.1/sbin autrijus-3.1/spec

autrijus at fsck.com autrijus at fsck.com
Thu Mar 4 10:50:06 EST 2004


Author: autrijus
Date: Thu Mar  4 10:50:03 2004
New Revision: 469

Added:
   rt/branches/autrijus-3.1/html/Admin/CustomFields/
   rt/branches/autrijus-3.1/html/Admin/CustomFields/GroupRights.html
   rt/branches/autrijus-3.1/html/Admin/CustomFields/Modify.html
   rt/branches/autrijus-3.1/html/Admin/CustomFields/UserRights.html
   rt/branches/autrijus-3.1/html/Admin/CustomFields/index.html
   rt/branches/autrijus-3.1/html/Admin/Elements/CustomFieldTabs
   rt/branches/autrijus-3.1/html/Admin/Elements/ObjectCustomFields
   rt/branches/autrijus-3.1/html/Admin/Elements/SelectCustomFieldObjectType
   rt/branches/autrijus-3.1/html/Admin/Groups/History.html
   rt/branches/autrijus-3.1/html/Admin/Users/CustomFields.html
   rt/branches/autrijus-3.1/html/Admin/Users/History.html
   rt/branches/autrijus-3.1/lib/RT/ObjectCustomField_Overlay.pm
   rt/branches/autrijus-3.1/lib/RT/ObjectCustomFields_Overlay.pm
   rt/branches/autrijus-3.1/spec/
   rt/branches/autrijus-3.1/spec/schema.txt
   rt/branches/autrijus-3.1/spec/spec.txt
Modified:
   rt/branches/   (props changed)
   rt/branches/autrijus-3.1/Makefile.in
   rt/branches/autrijus-3.1/README
   rt/branches/autrijus-3.1/UPGRADING
   rt/branches/autrijus-3.1/bin/webmux.pl.in
   rt/branches/autrijus-3.1/etc/acl.mysql
   rt/branches/autrijus-3.1/etc/schema.Informix
   rt/branches/autrijus-3.1/etc/schema.Oracle
   rt/branches/autrijus-3.1/etc/schema.Pg
   rt/branches/autrijus-3.1/etc/schema.SQLite
   rt/branches/autrijus-3.1/etc/schema.mysql
   rt/branches/autrijus-3.1/html/Admin/Elements/EditCustomFields
   rt/branches/autrijus-3.1/html/Admin/Elements/GroupTabs
   rt/branches/autrijus-3.1/html/Admin/Elements/QueueTabs
   rt/branches/autrijus-3.1/html/Admin/Elements/SelectCustomFieldType
   rt/branches/autrijus-3.1/html/Admin/Elements/SelectRights
   rt/branches/autrijus-3.1/html/Admin/Elements/SystemTabs
   rt/branches/autrijus-3.1/html/Admin/Elements/Tabs
   rt/branches/autrijus-3.1/html/Admin/Elements/UserTabs
   rt/branches/autrijus-3.1/html/Admin/Global/index.html
   rt/branches/autrijus-3.1/html/Admin/Groups/Modify.html
   rt/branches/autrijus-3.1/html/Admin/Queues/CustomField.html
   rt/branches/autrijus-3.1/html/Admin/Queues/CustomFields.html
   rt/branches/autrijus-3.1/html/Admin/Queues/Modify.html
   rt/branches/autrijus-3.1/html/Admin/Users/Modify.html
   rt/branches/autrijus-3.1/html/Admin/index.html
   rt/branches/autrijus-3.1/html/Elements/Callback
   rt/branches/autrijus-3.1/html/Elements/MyRequests
   rt/branches/autrijus-3.1/html/Elements/MyTickets
   rt/branches/autrijus-3.1/html/Elements/SetupSessionCookie
   rt/branches/autrijus-3.1/html/Elements/TicketList
   rt/branches/autrijus-3.1/html/NoAuth/webrt.css
   rt/branches/autrijus-3.1/html/Projects/Elements/OverviewEntry
   rt/branches/autrijus-3.1/html/Projects/Elements/SelectProjectTaskEntry
   rt/branches/autrijus-3.1/html/Projects/Overview.html
   rt/branches/autrijus-3.1/html/Search/Build.html
   rt/branches/autrijus-3.1/html/Search/Elements/PickRestriction
   rt/branches/autrijus-3.1/html/Ticket/Attachment/dhandler
   rt/branches/autrijus-3.1/html/Ticket/Elements/ShowAttachments
   rt/branches/autrijus-3.1/html/Ticket/Elements/ShowHistory
   rt/branches/autrijus-3.1/html/Ticket/Elements/ShowMessageHeaders
   rt/branches/autrijus-3.1/html/Ticket/Elements/ShowMessageStanza
   rt/branches/autrijus-3.1/html/Ticket/Elements/ShowTransaction
   rt/branches/autrijus-3.1/html/autohandler
   rt/branches/autrijus-3.1/lib/RT/Action/SendEmail.pm
   rt/branches/autrijus-3.1/lib/RT/Attachment_Overlay.pm
   rt/branches/autrijus-3.1/lib/RT/CustomField.pm
   rt/branches/autrijus-3.1/lib/RT/CustomField_Overlay.pm
   rt/branches/autrijus-3.1/lib/RT/CustomFields_Overlay.pm
   rt/branches/autrijus-3.1/lib/RT/Group_Overlay.pm
   rt/branches/autrijus-3.1/lib/RT/Handle.pm
   rt/branches/autrijus-3.1/lib/RT/ObjectCustomField.pm
   rt/branches/autrijus-3.1/lib/RT/ObjectCustomFields.pm
   rt/branches/autrijus-3.1/lib/RT/Queue_Overlay.pm
   rt/branches/autrijus-3.1/lib/RT/Record.pm
   rt/branches/autrijus-3.1/lib/RT/StyleGuide.pod
   rt/branches/autrijus-3.1/lib/RT/Ticket_Overlay.pm
   rt/branches/autrijus-3.1/lib/RT/User_Overlay.pm
   rt/branches/autrijus-3.1/lib/RT/Users_Overlay.pm
   rt/branches/autrijus-3.1/releng.cnf
   rt/branches/autrijus-3.1/sbin/rt-setup-database.in
   rt/branches/autrijus-3.1/sbin/rt-test-dependencies.in
Log:
* display and modification of user/group CFs.


Modified: rt/branches/autrijus-3.1/Makefile.in
==============================================================================
--- rt/branches/autrijus-3.1/Makefile.in	(original)
+++ rt/branches/autrijus-3.1/Makefile.in	Thu Mar  4 10:50:03 2004
@@ -209,9 +209,12 @@
 	@echo "$(CONFIG_FILE) for any necessary site customization. Additionally,"
 	@echo "you should update RT's system database objects by running "
 	@echo "   ls etc/upgrade"
-	@echo "For each file in that directory whose name is greater than"
+	@echo ""
+	@echo "For each item in that directory whose name is greater than"
 	@echo "your previously installed RT version, run:"
-	@echo "	   $(RT_SBIN_PATH)/rt-setup-database --action insert --datafile etc/upgrade/<version>"
+	@echo "	   $(RT_SBIN_PATH)/rt-setup-database --action schema --datadir etc/upgrade/<version>"
+	@echo "	   $(RT_SBIN_PATH)/rt-setup-database --action acl --datadir etc/upgrade/<version>"
+	@echo "	   $(RT_SBIN_PATH)/rt-setup-database --action insert --datadir etc/upgrade/<version>"
 
 
 upgrade: config-install dirs files-install fixperms upgrade-instruct

Modified: rt/branches/autrijus-3.1/README
==============================================================================
--- rt/branches/autrijus-3.1/README	(original)
+++ rt/branches/autrijus-3.1/README	Thu Mar  4 10:50:03 2004
@@ -1,6 +1,6 @@
 # BEGIN LICENSE BLOCK
 # 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+# Copyright (c) 1996-2004 Jesse Vincent <jesse at bestpractical.com>
 # 
 # (Except where explictly superceded by other copyright notices)
 # 
@@ -29,35 +29,36 @@
 General Public License (GPL), so it doesn't cost anything to set
 up and use.
 
+RT is commercially supported software. To purchase consulting services, 
+support or training, please write to sales at bestpractical.com
 
         Jesse Vincent
         Best Practical Solutions, LLC
         March 2003
 
+
+
+
+
 REQUIRED PACKAGES:
 ------------------
 
-o   Perl 5.8.0 or later (http://www.perl.com).
+o   Perl 5.8.3 or later (http://www.perl.com).
 
  	(If you intend to use the FastCGI or SpeedyCGI support, you 
 	 need to make sure that perl has been built with support for 
 	 setgid perl scripts.)`
 
+    Perl versions prior to 5.8.3 contain bugs that could result in data
+    corruption. We recommend strongly that you use 5.8.3 or newer.
+
     Perl 5.6.1 is currently deprecated and will be officially desupported
     in a future release
 
 o   A DB backend; MySQL is recommended ( http://www.mysql.com ) 
         Currently supported:  Mysql 4.0.13 or later. 
                               Postgres 7.2 or later.
-
-                              Mysql 3.23.46 or newer with support for InnoDB 
-			      is currently deprecated and will be officially
-			      desupported in a future release.
-
-        Future support:       Oracle 9i.
-                              Oracle support has reached beta status and
-                              is being made available to further support
-                              this database for all RT functionality.
+                              Oracle 9iR2.
 
 o   Apache version 1.3.x or 2.x (http://httpd.apache.org) 
     with mod_perl -- (http://perl.apache.org ) 
@@ -155,7 +156,7 @@
                 make dropdb 
         and start over from step 5a
 
-5b  FOR UPGRADING: (Within the RT 3.0.x series)
+5b  FOR UPGRADING: (Within the RT 3.x series)
 
 
         Read through the UPGRADING document included in this distribution.

Modified: rt/branches/autrijus-3.1/UPGRADING
==============================================================================
--- rt/branches/autrijus-3.1/UPGRADING	(original)
+++ rt/branches/autrijus-3.1/UPGRADING	Thu Mar  4 10:50:03 2004
@@ -13,56 +13,10 @@
 
 UPGRADING FROM 3.0.x - Changes:
 
-Now, if you want RT to automatically create new users upon ticket submission, you MUST grant 'Everyone' the right to create tickets.
+Now, if you want RT to automatically create new users upon ticket
+submission, you MUST grant 'Everyone' the right to create tickets.
 Granting this right only to "Unprivileged Users" is now insufficient.
 
-
-
-
-----------------------------------------------------------------------
-
-3.0.7
-=====
-
-All Databases
--------------
-
-If you are upgrading from versions between 3.0.0 and 3.0.7, inclusive,
-you might find improved performance by adding the following index to
-your database:
-
-CREATE INDEX Links4 ON Links(Type,LocalBase);
-
-
-
-3.0.6
-=====
-
-
-All Databases
--------------
-
-If you are upgrading from versions between 3.0.0 and 3.0.6, inclusive,
-you might find improved performance by adding the following indices to
-your database:
-
-   CREATE INDEX TicketCustomFieldValues1 ON TicketCustomFieldValues (CustomField,Ticket,Content); 
-   CREATE INDEX TicketCustomFieldValues2 ON TicketCustomFieldValues (CustomField,Ticket); 
-
-   CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField);
-
-
-
-Postgres
---------
-
-If you have a Postgres database, the following changes to your
-database can improve performance:
-
-  ALTER TABLE groups rename instance to instance1;
-  ALTER TABLE groups add instance int;
-  UPDATE groups SET instance = instance1::text::int where btrim(instance1) <> '';
-  ALTER TABLE groups drop column instance1;
 
 
 

Modified: rt/branches/autrijus-3.1/bin/webmux.pl.in
==============================================================================
--- rt/branches/autrijus-3.1/bin/webmux.pl.in	(original)
+++ rt/branches/autrijus-3.1/bin/webmux.pl.in	Thu Mar  4 10:50:03 2004
@@ -88,7 +88,8 @@
     use RT::GroupMembers;
     use RT::CustomFields;
     use RT::CustomFieldValues;
-    use RT::TicketCustomFieldValues;
+    use RT::ObjectCustomFields;
+    use RT::ObjectCustomFieldValues;
 
     use RT::Interface::Web;
     use MIME::Entity;

Modified: rt/branches/autrijus-3.1/etc/acl.mysql
==============================================================================
--- rt/branches/autrijus-3.1/etc/acl.mysql	(original)
+++ rt/branches/autrijus-3.1/etc/acl.mysql	Thu Mar  4 10:50:03 2004
@@ -1,4 +1,5 @@
 sub acl {
+return () if $RT::DatabaseUser eq 'root';
 return  (
 "USE mysql;",
 "DELETE FROM user WHERE user = '${RT::DatabaseUser}';",

Modified: rt/branches/autrijus-3.1/etc/schema.Informix
==============================================================================
--- rt/branches/autrijus-3.1/etc/schema.Informix	(original)
+++ rt/branches/autrijus-3.1/etc/schema.Informix	Thu Mar  4 10:50:03 2004
@@ -347,6 +347,11 @@
 	LastUpdated	DATETIME YEAR TO SECOND,
         PRIMARY KEY (id)
 ); 
+
+CREATE INDEX Attributes1 on Attributes(Name);
+CREATE INDEX Attributes2 on Attributes(ObjectType, ObjectId);
+
+
 CREATE TABLE sessions (
 	id		VARCHAR(32) NOT NULL,
 	a_session	BYTE,

Modified: rt/branches/autrijus-3.1/etc/schema.Oracle
==============================================================================
--- rt/branches/autrijus-3.1/etc/schema.Oracle	(original)
+++ rt/branches/autrijus-3.1/etc/schema.Oracle	Thu Mar  4 10:50:03 2004
@@ -1,6 +1,7 @@
 CREATE SEQUENCE ATTACHMENTS_seq;
 CREATE TABLE Attachments (
-  	id 		NUMBER(11,0) PRIMARY KEY,
+  	id 		NUMBER(11,0) 
+			CONSTRAINT Attachments_Key PRIMARY KEY,
   	TransactionId	NUMBER(11,0) NOT NULL,
 	Parent 		NUMBER(11,0) DEFAULT 0 NOT NULL, 
   	MessageId 	VARCHAR2(160),
@@ -13,15 +14,15 @@
 	Creator 	NUMBER(11,0) DEFAULT 0 NOT NULL,
   	Created 	DATE
 );
-CREATE INDEX Attachments1 ON Attachments (Parent);
 CREATE INDEX Attachments2 ON Attachments (TransactionId);
 CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId);
 
 
 CREATE SEQUENCE QUEUES_seq;
 CREATE TABLE Queues (
-	id 			NUMBER(11,0) PRIMARY KEY,
-	Name 			VARCHAR2(200) UNIQUE NOT NULL,
+	id 			NUMBER(11,0) 
+		CONSTRAINT Queues_Key PRIMARY KEY,
+	Name 			VARCHAR2(200) CONSTRAINT Queues_Name_Unique UNIQUE NOT NULL,
 	Description 		VARCHAR2(255),
 	CorrespondAddress 	VARCHAR2(120),
 	CommentAddress 		VARCHAR2(120),
@@ -34,13 +35,14 @@
 	LastUpdated		DATE,
 	Disabled 		NUMBER(11,0) DEFAULT 0 NOT NULL
 );
--- CREATE UNIQUE INDEX Queues1 ON Queues (Name);
+ CREATE  INDEX Queues1 ON Queues (lower(Name));
 CREATE INDEX Queues2 ON Queues (Disabled);
 
 
 CREATE SEQUENCE LINKS_seq;
 CREATE TABLE Links (
-  	id 		NUMBER(11,0) PRIMARY KEY,
+  	id 		NUMBER(11,0) 
+		CONSTRAINT Links_Key PRIMARY KEY,
 	Base 		VARCHAR2(240),
 	Target 		VARCHAR2(240),
   	Type 		VARCHAR2(20) NOT NULL,
@@ -59,17 +61,19 @@
 
 CREATE SEQUENCE PRINCIPALS_seq;
 CREATE TABLE Principals (
-	id		NUMBER(11,0) PRIMARY KEY,
+	id		NUMBER(11,0) 
+		CONSTRAINT Principals_Key PRIMARY KEY,
 	PrincipalType	VARCHAR2(16),
 	ObjectId	NUMBER(11,0),
 	Disabled	NUMBER(11,0) DEFAULT 0 NOT NULL
 );
-CREATE INDEX Principals2 ON Principals (ObjectId);
+CREATE UNIQUE  INDEX Principals2 ON Principals (ObjectId);
 
 
 CREATE SEQUENCE GROUPS_seq;
 CREATE TABLE Groups (
-	id 		NUMBER(11,0) PRIMARY KEY,
+	id 		NUMBER(11,0) 
+		CONSTRAINT Groups_Key PRIMARY KEY,
 	Name 		VARCHAR2(200),
 	Description 	VARCHAR2(255),
 	Domain		VARCHAR2(64),
@@ -77,13 +81,14 @@
 	Instance	NUMBER(11,0) DEFAULT 0 -- NOT NULL
 --	Instance	VARCHAR2(64)
 );
-CREATE INDEX Groups1 ON Groups (Domain, Instance, Type, id);
-CREATE INDEX Groups2 ON Groups (Type, Instance, Domain);
+CREATE INDEX Groups1 ON Groups (lower( Domain), Instance, lower(Type), id);
+CREATE INDEX Groups2 ON Groups (lower(Type), Instance, lower(Domain));
 
 
 CREATE SEQUENCE SCRIPCONDITIONS_seq;
 CREATE TABLE ScripConditions (
- 	id 			NUMBER(11, 0) PRIMARY KEY,
+ 	id 			NUMBER(11, 0) 
+		CONSTRAINT ScripConditions_Key PRIMARY KEY,
 	Name 			VARCHAR2(200),
 	Description 		VARCHAR2(255),
 	ExecModule		VARCHAR2(60),
@@ -98,7 +103,8 @@
 
 CREATE SEQUENCE TRANSACTIONS_seq;
 CREATE TABLE Transactions (
-  	id 			NUMBER(11,0) PRIMARY KEY,
+  	id 			NUMBER(11,0) 
+		CONSTRAINT Transactions_Key PRIMARY KEY,
   	EffectiveTicket 	NUMBER(11,0) DEFAULT 0 NOT NULL,
   	Ticket 			NUMBER(11,0) DEFAULT 0 NOT NULL,
   	TimeTaken 		NUMBER(11,0) DEFAULT 0 NOT NULL,
@@ -116,7 +122,8 @@
 
 CREATE SEQUENCE SCRIPS_seq;
 CREATE TABLE Scrips (
-  	id 		NUMBER(11,0) PRIMARY KEY,	
+  	id 		NUMBER(11,0) 
+		CONSTRAINT Scrips_Key PRIMARY KEY,	
 	Description	VARCHAR2(255),
 	ScripCondition 	NUMBER(11,0) DEFAULT 0 NOT NULL,
 	ScripAction	NUMBER(11,0) DEFAULT 0 NOT NULL,
@@ -137,7 +144,8 @@
 
 CREATE SEQUENCE ACL_seq;
 CREATE TABLE ACL (
-	id 		NUMBER(11,0) PRIMARY KEY,
+	id 		NUMBER(11,0) 
+		CONSTRAINT ACL_Key PRIMARY KEY,
 	PrincipalType 	VARCHAR2(25) NOT NULL,
 	PrincipalId 	NUMBER(11,0) NOT NULL,
 	RightName	VARCHAR2(25) NOT NULL,
@@ -151,7 +159,8 @@
 
 CREATE SEQUENCE GROUPMEMBERS_seq;
 CREATE TABLE GroupMembers (
-	id 		NUMBER(11,0) PRIMARY KEY,
+	id 		NUMBER(11,0) 
+		CONSTRAINT GroupMembers_Key PRIMARY KEY,
 	GroupId 	NUMBER(11,0) DEFAULT 0 NOT NULL,
 	MemberId 	NUMBER(11,0) DEFAULT 0 NOT NULL
 );
@@ -160,7 +169,8 @@
 
 CREATE SEQUENCE CachedGroupMembers_seq;
 CREATE TABLE CachedGroupMembers (
-	id		NUMBER(11,0) PRIMARY KEY,
+	id		NUMBER(11,0) 
+		CONSTRAINT CachedGroupMembers_Key PRIMARY KEY,
 	GroupId		NUMBER(11,0),
 	MemberId	NUMBER(11,0),
 	Via		NUMBER(11,0),
@@ -173,8 +183,10 @@
 
 CREATE SEQUENCE USERS_seq;
 CREATE TABLE Users (
-  	id 			NUMBER(11,0) PRIMARY KEY,
-  	Name 			VARCHAR2(200) NOT NULL,
+  	id 			NUMBER(11,0) 
+		CONSTRAINT Users_Key PRIMARY KEY,
+  	Name 			VARCHAR2(200) CONSTRAINT Users_Name_Unique 
+		unique  NOT NULL,
   	Password 		VARCHAR2(40),
   	Comments 		CLOB,
   	Signature 		CLOB,
@@ -209,14 +221,15 @@
   	LastUpdated 		DATE
 );
 -- CREATE UNIQUE INDEX Users1 ON Users (Name);
-CREATE INDEX Users2 ON Users (Name);
-CREATE INDEX Users3 ON Users (id, EmailAddress);
-CREATE INDEX Users4 ON Users (EmailAddress);
+
+CREATE INDEX Users2 ON Users( LOWER(name));
+CREATE INDEX Users4 ON Users (lower(EmailAddress));
 
 
 CREATE SEQUENCE TICKETS_seq;
 CREATE TABLE Tickets (
-  	id			NUMBER(11, 0) PRIMARY KEY,
+       id                      NUMBER(11, 0) 
+               CONSTRAINT Tickets_Key PRIMARY KEY,
   	EffectiveId		NUMBER(11,0) DEFAULT 0 NOT NULL,
   	Queue 			NUMBER(11,0) DEFAULT 0 NOT NULL,
   	Type 			VARCHAR2(16), 		
@@ -244,7 +257,6 @@
 );
 CREATE INDEX Tickets1 ON Tickets (Queue, Status);
 CREATE INDEX Tickets2 ON Tickets (Owner);
-CREATE INDEX Tickets3 ON Tickets (EffectiveId);
 CREATE INDEX Tickets4 ON Tickets (id, Status);
 CREATE INDEX Tickets5 ON Tickets (id, EffectiveId);
 CREATE INDEX Tickets6 ON Tickets (EffectiveId, Type);
@@ -252,7 +264,8 @@
 
 CREATE SEQUENCE SCRIPACTIONS_seq;
 CREATE TABLE ScripActions (
-  id		NUMBER(11,0) PRIMARY KEY,
+  id		NUMBER(11,0) 
+		CONSTRAINT ScripActions_Key PRIMARY KEY,
   Name		VARCHAR2(200),
   Description	VARCHAR2(255),
   ExecModule	VARCHAR2(60),
@@ -266,7 +279,8 @@
 
 CREATE SEQUENCE TEMPLATES_seq;
 CREATE TABLE Templates (
-  	id 		NUMBER(11,0) PRIMARY KEY,
+  	id 		NUMBER(11,0) 
+		CONSTRAINT Templates_Key PRIMARY KEY,
 	Queue 		NUMBER(11,0) DEFAULT 0 NOT NULL,
 	Name		VARCHAR2(200) NOT NULL,
 	Description	VARCHAR2(255),
@@ -283,7 +297,8 @@
 
 CREATE SEQUENCE TICKETCUSTOMFIELDVALUES_seq;
 CREATE TABLE TicketCustomFieldValues (
-	id		NUMBER(11,0) PRIMARY KEY,
+	id		NUMBER(11,0) 
+		CONSTRAINT TicketCustomFieldValues_Key PRIMARY KEY,
 	Ticket		NUMBER(11,0),
 	CustomField	NUMBER(11,0) NOT NULL,
 	Content		VARCHAR2(255),
@@ -298,7 +313,8 @@
 
 CREATE SEQUENCE CUSTOMFIELDS_seq;
 CREATE TABLE CustomFields (
-	id		NUMBER(11,0) PRIMARY KEY,
+	id		NUMBER(11,0) 
+		CONSTRAINT CustomFields_Key PRIMARY KEY,
 	Name		VARCHAR2(200),
 	Type		VARCHAR2(200),
 	Queue		NUMBER(11,0) DEFAULT 0 NOT NULL,
@@ -315,7 +331,8 @@
 
 CREATE SEQUENCE CUSTOMFIELDVALUES_seq;
 CREATE TABLE CustomFieldValues (
-	id		NUMBER(11,0) PRIMARY KEY,
+	id		NUMBER(11,0) 
+		CONSTRAINT CustomFieldValues_Key PRIMARY KEY,
 	CustomField	NUMBER(11,0),
 	Name		VARCHAR2(200),
 	Description	VARCHAR2(255),
@@ -343,9 +360,13 @@
 	LastUpdated		DATE,
 );
 
+CREATE INDEX Attributes1 on Attributes(Name);
+CREATE INDEX Attributes2 on Attributes(ObjectType, ObjectId);
+
 
 CREATE TABLE sessions (
-	id		VARCHAR2(32) PRIMARY KEY,
+	id		VARCHAR2(32) 
+		CONSTRAINT Sessions_Key PRIMARY KEY,
 	a_session	CLOB,
 	LastUpdated	DATE
 );

Modified: rt/branches/autrijus-3.1/etc/schema.Pg
==============================================================================
--- rt/branches/autrijus-3.1/etc/schema.Pg	(original)
+++ rt/branches/autrijus-3.1/etc/schema.Pg	Thu Mar  4 10:50:03 2004
@@ -562,6 +562,8 @@
 -- }}}
 
 
+-- {{{ Attributes
+
 CREATE SEQUENCE attributes_id_seq;
 
 CREATE TABLE Attributes (
@@ -579,9 +581,11 @@
   PRIMARY KEY (id)
 
 );
-CREATE INDEX Attributes1 on Attributes(Name, ObjectType, ObjectId);
 
+CREATE INDEX Attributes1 on Attributes(Name);
+CREATE INDEX Attributes2 on Attributes(ObjectType, ObjectId);
 
+-- }}}
 
 -- {{{ Sessions
 

Modified: rt/branches/autrijus-3.1/etc/schema.SQLite
==============================================================================
--- rt/branches/autrijus-3.1/etc/schema.SQLite	(original)
+++ rt/branches/autrijus-3.1/etc/schema.SQLite	Thu Mar  4 10:50:03 2004
@@ -404,7 +404,8 @@
   LastUpdated DATETIME NULL  
  
 ) ;
-CREATE UNIQUE INDEX Attributes1 ON Attributes (Name) ;
+CREATE INDEX Attributes1 on Attributes(Name)
+CREATE INDEX Attributes2 on Attributes(ObjectType, ObjectId);
 
 --- }}}
 

Modified: rt/branches/autrijus-3.1/etc/schema.mysql
==============================================================================
--- rt/branches/autrijus-3.1/etc/schema.mysql	(original)
+++ rt/branches/autrijus-3.1/etc/schema.mysql	Thu Mar  4 10:50:03 2004
@@ -119,7 +119,7 @@
 # {{{ Transactions
 CREATE TABLE Transactions (
   id INTEGER NOT NULL  AUTO_INCREMENT,
-  ObjectType varchar(64),
+  ObjectType varchar(64) NOT NULL,
   ObjectId integer NOT NULL DEFAULT 0  ,
   TimeTaken integer NOT NULL DEFAULT 0  ,
   Type varchar(20) NULL  ,
@@ -351,7 +351,7 @@
 CREATE TABLE ObjectCustomFieldValues (
   id INTEGER NOT NULL  AUTO_INCREMENT,
   CustomField int NOT NULL  ,
-  ObjectType varchar(255) NULL,		    # Final target of the Object
+  ObjectType varchar(255) NOT NULL,		    # Final target of the Object
   ObjectId int NOT NULL  ,		    # New -- Replaces Ticket
 
   Current BOOL DEFAULT 1,		    # New -- whether the value was current
@@ -367,8 +367,8 @@
   PRIMARY KEY (id)
 ) TYPE=InnoDB;
 
-CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId,Content); 
-CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId); 
+CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (CustomField,ObjectId,Content); 
+CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,ObjectId); 
 
 # }}}
 
@@ -380,9 +380,14 @@
   Type varchar(200) NULL  ,	# Changed -- 'Single' and 'Multiple' is moved out
   MaxValues integer,		# New -- was 'Single'(1) and 'Multiple'(0)
   Pattern varchar(255) NULL  ,	# New -- Must validate against this
+  Repeated int2 NOT NULL DEFAULT 0 , # New -- repeated table entry
   Description varchar(255) NULL  ,
   SortOrder integer NOT NULL DEFAULT 0  ,
 
+  ObjectType varchar(255) NOT NULL,
+  IntermediateType varchar(255) NOT NULL,
+  ParentType varchar(255) NOT NULL,
+
   Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
@@ -398,10 +403,8 @@
 CREATE TABLE ObjectCustomFields (
   id INTEGER NOT NULL  AUTO_INCREMENT,
   CustomField int NOT NULL  ,
-  ObjectType varchar(255) NULL,
-  IntermediateType varchar(255) NULL,
-  ParentType varchar(255) NULL,
   ParentId integer NOT NULL,
+  SortOrder integer NOT NULL DEFAULT 0  ,
 
   Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,

Added: rt/branches/autrijus-3.1/html/Admin/CustomFields/GroupRights.html
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/CustomFields/GroupRights.html	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,140 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
+%#  
+%#  This program is free software; you can redistribute it and/or modify
+%#  it under the terms of version 2 of the GNU General Public License 
+%#  as published by the Free Software Foundation.
+%# 
+%#  A copy of that license should have arrived with this
+%#  software, but in any event can be snarfed from www.gnu.org.
+%# 
+%#  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.
+%# 
+%# END LICENSE BLOCK
+
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/CustomFieldTabs, id => $id, current_subtab =>
+"Admin/CustomFields/UserRights.html?id=".$id, Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+  <FORM METHOD=POST ACTION="GroupRights.html">
+    <INPUT TYPE=HIDDEN NAME=id VALUE="<% $CustomFieldObj->id %>">
+      
+      
+<h1><&|/l&>System groups</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToSystemInternalGroups();
+%	while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+	<TD VALIGN=TOP>
+	    <% loc($Group->Type) %>
+		  </TD>
+	  <TD>
+	    <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        Object => $CustomFieldObj  &>
+	  </TD>
+	</TR>
+% }
+</TABLE>
+<h1><&|/l&>User defined groups</&></h1>
+<TABLE>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToUserDefinedGroups();    
+%	while (my $Group = $Groups->Next()) {
+  <TR ALIGN=RIGHT> 
+	<TD VALIGN=TOP>
+	    <% $Group->Name %>
+		  </TD>
+	  <TD>
+	    <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+        Object => $CustomFieldObj  &>
+	  </TD>
+	</TR>
+% }
+</TABLE>
+            
+      <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+      
+  </FORM>
+  
+<%INIT>
+ 
+
+
+
+  
+
+if (!defined $id) {
+    $m->comp("/Elements/Error", Why => loc("No CustomField defined"));
+}
+
+my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+$CustomFieldObj->Load($id) || $m->comp("/Elements/Error", Why => loc("Couldn't load CustomField [_1]",$id));
+
+my $Groups;
+  
+  my ( $ACL, @results );
+
+    foreach my $arg (keys %ARGS) {
+        if ($arg =~ /GrantRight-(\d+)-(.*?)-(\d+)$/) {
+            my $principal_id = $1;
+            my $object_type = $2;
+            my $object_id = $3;
+            my $rights = $ARGS{$arg};
+
+            my $principal = RT::Principal->new($session{'CurrentUser'});
+            $principal->Load($principal_id);
+            my $obj;
+
+            if ($object_type eq 'RT::CustomField') {
+                $obj = RT::CustomField->new($session{'CurrentUser'});
+                $obj->Load($object_id);
+            } else {
+                push (@results, loc("System Error").
+                                loc("Rights could not be granted for [_1]", $object_type));
+                next;
+            }
+
+            my @rights = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg});
+            foreach my $right (@rights) {
+                next unless ($right);
+                my ($val, $msg) = $principal->GrantRight(Object => $obj, Right => $right);
+                push (@results, $msg);
+            }
+        }
+     elsif ($arg =~ /RevokeRight-(\d+)-(.*?)-(\d+)-(.*?)$/) {
+            my $principal_id = $1;
+            my $object_type = $2;
+            my $object_id = $3;
+            my $right = $4;
+
+            my $principal = RT::Principal->new($session{'CurrentUser'});
+            $principal->Load($principal_id);
+            next unless ($right);
+            my $obj;
+
+            if ($object_type eq 'RT::CustomField') {
+                $obj = RT::CustomField->new($session{'CurrentUser'});
+                $obj->Load($object_id);
+            } else {
+                push (@results, loc("System Error").
+                                loc("Rights could not be revoked for [_1]", $object_type));
+                next;
+            }
+            my ($val, $msg) = $principal->RevokeRight(Object => $obj, Right => $right);
+            push (@results, $msg);
+        }
+} 
+
+my $title = loc('Modify group rights for custom field [_1]', $CustomFieldObj->Name);
+    
+</%INIT>
+
+<%ARGS>
+$id => undef
+</%ARGS>

Added: rt/branches/autrijus-3.1/html/Admin/CustomFields/Modify.html
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/CustomFields/Modify.html	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,165 @@
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/CustomFieldTabs, id => $CustomFieldObj->Id ,
+current_subtab => $current_subtab,
+Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+<FORM METHOD="POST" ACTION="Modify.html">
+<INPUT TYPE=HIDDEN NAME="id" VALUE="<%$id %>">
+<table>
+<tr>
+<td class="label"><&|/l&>Name</&></td>
+<td><input name="Name" VALUE="<%$CustomFieldObj->Name%>" SIZE=20></td></tr>
+<tr>
+<td class="label"><&|/l&>Description</&></td>
+<td><input name="Description" VALUE="<%$CustomFieldObj->Description%>" SIZE=80></td>
+</tr>
+
+<tr>
+<td class="label"><&|/l&>Type</&></td>
+<td><& /Admin/Elements/SelectCustomFieldType, 
+        Name => "TypeComposite", 
+        Default => $CustomFieldObj->TypeComposite, &>
+</td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Applies to</&></td>
+<td><& /Admin/Elements/SelectCustomFieldObjectType, 
+        Name => "ObjectTypeComposite", 
+        Default => $CustomFieldObj->ObjectTypeComposite, &>
+</td>
+</tr>
+<tr>
+<td class="label">&nbsp;</td>
+<td>
+<INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
+<INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>> <&|/l&>Enabled (Unchecking this box disables this custom field)</&>
+</td>
+</tr>
+<BR>
+% if ($CustomFieldObj->Id && $CustomFieldObj->Type =~ /^Select/i) {
+<H2><&|/l&>Values</&></H2>
+<div>
+<& /Admin/Elements/EditCustomFieldValues, CustomField => $CustomFieldObj &>
+<& /Admin/Elements/AddCustomFieldValue, CustomField => $CustomFieldObj &>
+</div>
+% }
+<&/Elements/Submit&>
+</FORM>
+
+
+
+<%INIT>
+
+
+
+my $CustomFieldObj = RT::CustomField->new( $session{'CurrentUser'} );
+my ( $title, @results, $EnabledChecked, $Disabled);
+$EnabledChecked = "CHECKED";
+
+if ( !$id ) {
+    $title = loc("Create a CustomField");
+    $id    = 'new';
+}
+else {
+
+    if ( $id eq 'new' ) {
+        my ( $val, $msg ) = $CustomFieldObj->Create(Name        => $Name,
+                                                    TypeComposite => $TypeComposite,
+                                                    ObjectTypeComposite => $ObjectTypeComposite,
+                                                    Description => $Description,);
+        $m->comp("/Elements/Error", Why =>  loc( "Could not create CustomField", $msg ) ) unless ($val);
+        push @results, $msg;
+        $title = loc( 'Created CustomField [_1]', $CustomFieldObj->Name() );
+    }
+    else {
+        $CustomFieldObj->Load($id) || $m->comp("/Elements/Error", Why =>  loc('No CustomField') );
+        $title = loc( 'Editing CustomField [_1]', $CustomFieldObj->Name() );
+
+        my @attribs = qw( Name TypeComposite ObjectTypeComposite Description);
+        my @aresults = UpdateRecordObject( AttributesRef => \@attribs,
+                                           Object        => $CustomFieldObj,
+                                           ARGSRef       => \%ARGS );
+
+        push @results, @aresults;
+
+	#we're asking about enabled on the web page but really care about disabled.
+	if ($Enabled == 1) {
+	    $Disabled = 0;
+	}	
+	else {
+	    $Disabled = 1;
+	}
+	if  ( ($SetEnabled) and ( $Disabled != $CustomFieldObj->Disabled) ) { 
+	    my  ($code, $msg) = $CustomFieldObj->SetDisabled($Disabled);
+	    push @results, loc('Enabled status: [_1]', loc_fuzzy($msg));
+	}
+	
+	if ($CustomFieldObj->Disabled()) {
+	    $EnabledChecked ="";
+	}
+    }
+
+    $id = $CustomFieldObj->id;
+}
+
+
+
+
+my $paramtag = "CustomField-".$CustomFieldObj->Id."-Value-";
+# Delete any fields that want to be deleted
+foreach my $key (keys %ARGS) {
+	
+	next unless ($key =~ /^Delete-$paramtag(\d+)$/);
+	my ($val, $msg) = $CustomFieldObj->DeleteValue($1);
+	push (@results, $msg);
+
+
+}
+# Update any existing values
+my $values = $CustomFieldObj->ValuesObj;
+while (my $value = $values->Next) {
+	foreach my $attr qw(Name Description SortOrder) {
+	my $param = $paramtag.$value->Id."-".$attr;
+
+	if ( $ARGS{$param} && ($value->$attr() ne $ARGS{$param}))  {
+		my $mutator = "Set$attr";
+		my ($id, $msg) = $value->$mutator($ARGS{$param});
+        push (@results, $msg);
+		}
+	}
+
+
+}
+
+
+
+# Add any new values
+if ($ARGS{$paramtag."new-Name"}) {
+	my ($id, $msg) = $CustomFieldObj->AddValue ( Name => $ARGS{$paramtag."new-Name"},
+						 Description => $ARGS{$paramtag."new-Description"},
+						 SortOrder => $ARGS{$paramtag."new-SortOrder"});
+	push (@results, $msg);
+}
+
+my $current_subtab;
+if ($ARGS{'Create'}){ 
+    $current_subtab = "Admin/CustomFields/Modify.html?Create=1";
+} else {
+    $current_subtab = "Admin/CustomFields/Modify.html?id=".$id;
+    }
+
+
+</%INIT>
+<%ARGS>
+$id => undef
+$TypeComposite => undef
+$ObjectTypeComposite => undef
+$MaxValues => undef
+$SortOrder => undef
+$Description => undef
+$Name => undef
+$SetEnabled => undef
+$Enabled => undef
+</%ARGS>

Added: rt/branches/autrijus-3.1/html/Admin/CustomFields/UserRights.html
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/CustomFields/UserRights.html	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,141 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
+%#  
+%#  This program is free software; you can redistribute it and/or modify
+%#  it under the terms of version 2 of the GNU General Public License 
+%#  as published by the Free Software Foundation.
+%# 
+%#  A copy of that license should have arrived with this
+%#  software, but in any event can be snarfed from www.gnu.org.
+%# 
+%#  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.
+%# 
+%# END LICENSE BLOCK
+
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/CustomFieldTabs, id => $id, 
+current_subtab => "Admin/CustomFields/UserRights.html?id=".$id,
+Title => $title, &>
+<& /Elements/ListActions, actions => \@results &>
+
+  <FORM METHOD=POST ACTION="UserRights.html">
+    <INPUT TYPE=HIDDEN NAME=id VALUE="<% $CustomFieldObj->id %>">
+      
+      
+<TABLE>
+        
+%	while (my $Member = $Users->Next()) {
+% my $UserObj = $Member->MemberObj->Object();
+% my $group = RT::Group->new($session{'CurrentUser'});
+% $group->LoadACLEquivalenceGroup($Member->MemberObj);
+  <TR ALIGN=RIGHT> 
+	<TD VALIGN=TOP>
+	    <% $UserObj->Name %>
+		  </TD>
+	  <TD>
+	    <& /Admin/Elements/SelectRights, PrincipalId=> $group->PrincipalId,
+        Object => $CustomFieldObj  &>
+	  </TD>
+	</TR>
+% }
+      </TABLE>
+            
+      <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+      
+  </FORM>
+  
+<%INIT>
+ 
+  #Update the acls.
+  my @results;
+foreach my $arg (keys %ARGS) {
+        if ($arg =~ /GrantRight-(\d+)-(.*?)-(\d+)$/) {
+            my $principal_id = $1;
+            my $object_type = $2;
+            my $object_id = $3;
+            my $rights = $ARGS{$arg};
+
+            my $principal = RT::Principal->new($session{'CurrentUser'});
+            $principal->Load($principal_id);
+            my $obj;
+
+            if ($object_type eq 'RT::CustomField') {
+                $obj = RT::CustomField->new($session{'CurrentUser'});
+                $obj->Load($object_id);
+
+            } else {
+                push (@results, loc("System Error").
+                                loc("Rights could not be granted for [_1]",
+$object_type));
+                next;
+            }
+
+            my @rights = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} :
+($ARGS{$arg});
+            foreach my $right (@rights) {
+                next unless ($right);
+                my ($val, $msg) = $principal->GrantRight(Object => $obj, Right
+=> $right);
+                push (@results, $msg);
+            }
+        }
+     elsif ($arg =~ /RevokeRight-(\d+)-(.*?)-(\d+)-(.*?)$/) {
+            my $principal_id = $1;
+            my $object_type = $2;
+            my $object_id = $3;
+            my $right = $4;
+
+            my $principal = RT::Principal->new($session{'CurrentUser'});
+            $principal->Load($principal_id);
+            next unless ($right);
+            my $obj;
+
+            if ($object_type eq 'RT::Class') {
+                $obj = RT::Class->new($session{'CurrentUser'});
+                $obj->Load($object_id);
+            } else {
+                push (@results, loc("System Error").
+                                loc("Rights could not be revoked for [_1]",
+$object_type));
+                next;
+            }
+            my ($val, $msg) = $principal->RevokeRight(Object => $obj, Right =>
+$right);
+            push (@results, $msg);
+        }
+} 
+  
+
+# {{{ Deal with setting up the display of current rights.
+
+
+
+if (!defined $id) {
+    $m->comp("/Elements/Error", Why => loc("No Class defined"));
+}
+
+my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+$CustomFieldObj->Load($id) || $m->comp("/Elements/Error", Why => loc("Couldn't load Class [_1]",$id));
+
+# Find out which users we want to display ACL selects for
+my $Privileged = RT::Group->new($session{'CurrentUser'});
+$Privileged->LoadSystemInternalGroup('Privileged');
+my $Users = $Privileged->MembersObj();
+
+    
+my $title = loc('Modify user rights for custom field [_1]', $CustomFieldObj->Name);
+  
+# }}}
+    
+</%INIT>
+
+<%ARGS>
+$id => undef
+$UserString => undef
+$UserOp => undef
+$UserField => undef
+</%ARGS>

Added: rt/branches/autrijus-3.1/html/Admin/CustomFields/index.html
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/CustomFields/index.html	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,19 @@
+<& /Admin/Elements/Header, Title => loc('Select a Custom Field') &>
+<& /Admin/Elements/CustomFieldTabs, current_tab => 'Admin/CustomFields/', 
+    current_subtab => 'Admin/CustomFields/',
+    Title => loc('Select a Custom Field') &>
+
+<UL>
+%while  (my $CustomFieldObj = $CustomFields->Next) { 
+%    $CustomFieldObj->CurrentUserHasRight('AdminCustomField') or next;
+
+<LI>
+<A HREF="Modify.html?id=<%$CustomFieldObj->id()%>"><%$CustomFieldObj->Name%>: <%$CustomFieldObj->Description%></a> (<%$CustomFieldObj->FriendlyObjectTypeComposite%>)<BR>
+
+%}
+
+<%INIT>
+my $CustomFields = RT::CustomFields->new($session{'CurrentUser'});
+$CustomFields->UnLimit();
+$CustomFields->OrderByCols(map { +{ FIELD => $_ } } qw( ObjectType IntermediateType ParentType ) );
+</%INIT>

Added: rt/branches/autrijus-3.1/html/Admin/Elements/CustomFieldTabs
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/CustomFieldTabs	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,66 @@
+<& /Admin/Elements/Tabs, 
+    subtabs => $tabs, 
+    current_tab => 'Admin/CustomFields/', 
+    current_subtab => $current_subtab, 
+    Title => $Title &>
+<%INIT>
+my $tabs;
+
+if ($id) {
+    my $cf = RT::CustomField->new( $session{'CurrentUser'} );
+    $cf->Load($id);
+    $tabs = {
+        C => {
+            title => $cf->Name,
+            path  => "Admin/CustomFields/Modify.html?id=" . $id,
+
+            subtabs => {
+
+                C => { title => loc('Basics'),
+                       path  => "Admin/CustomFields/Modify.html?id=" . $id,
+                },
+
+                F => { title => loc('Group Rights'),
+                       path  => "Admin/CustomFields/GroupRights.html?id="
+                         . $id, },
+                G => {
+                    title => loc('User Rights'),
+                    path => "Admin/CustomFields/UserRights.html?id=" . $id,
+                },
+
+            } }
+
+    };
+}
+
+if ($session{'CurrentUser'}->HasRight( Object => $RT::System, Right => 'AdminCustomField')) {
+  $tabs->{"A"} = { title => loc('Select custom field'),
+                        path => "Admin/CustomFields/",
+                           };
+  $tabs->{"B"} = { title => loc('New custom field'),
+                        path => "Admin/CustomFields/Modify.html?Create=1",
+                        separator => 1,
+                           };
+}
+
+  # Now let callbacks add their extra tabs
+  $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+foreach my $tab ( sort keys %{$tabs} ) {                                        
+    if ( $tabs->{$tab}->{'path'} eq $current_subtab ) {                         
+        $tabs->{$tab}->{"current_subtab"} = $current_subtab;                    
+    }                                                                           
+  foreach my $subtab (sort keys %{$tabs->{'subtabs'}}) {
+    if ($tabs->{$tab}->{subtabs}->{$subtab}->{'path'} eq $current_tab) {
+      $tabs->{$tab}->{subtabs}->{$subtab}->{"current_subtab"} = $current_subtab;
+    }
+  }
+}                                                                               
+
+</%INIT>
+<%ARGS>
+$id => undef
+$current_subtab => undef
+$current_tab => undef
+$Title => undef
+</%ARGS>

Modified: rt/branches/autrijus-3.1/html/Admin/Elements/EditCustomFields
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Elements/EditCustomFields	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/EditCustomFields	Thu Mar  4 10:50:03 2004
@@ -21,74 +21,48 @@
 %# 
 %# 
 %# END LICENSE BLOCK
-<& /Elements/ListActions, actions => \@actions &>
+<& /Elements/ListActions, actions => \@results &>
 
 <TABLE>
 <TR>
 <TD VALIGN=TOP>
 <h2><%$caption%></h2>
 </TD></TR></TABLE>
-% if ($CustomFields->Count == 0 ) {
-<P><i><&|/l&>(No custom fields)</&></i></P>
-% } else {
-<TABLE cellspacing=0 cellpadding=2>
-% my $count;
-% while (my $CustomFieldObj = $CustomFields->Next) { 
-<TR>
-  <TD valign="TOP">
-% if ($CustomFieldObj->Name) {
-    <A HREF="CustomField.html?Queue=<%$id%>&CustomField=<%$CustomFieldObj->id()%>"><b><%$CustomFieldObj->Name%></b></a><br>
-% } else {
-    <A HREF="CustomField.html?Queue=<%$id%>&CustomField=<%$CustomFieldObj->id()%>"><i>(<%loc("no name")%>)</i></a><br>
-% }
-    <%$CustomFieldObj->Description%>
-  </TD>
-  <TD valign="TOP">
-    <i><% $CustomFieldObj->FriendlyType %></i>
-  </TD>
-%  # show 'move up' unless it's the first item
-%  if ($count++) {
-  <TD valign="TOP">
-    <a href="CustomFields.html?id=<%$id%>&CustomField=<%$CustomFieldObj->id%>&Move=-1"><&|/l&>Move up</&></a>
-%  } else {
-  <TD valign="TOP" ALIGN=RIGHT>
-%  }
-
-%  # show 'move down' unless it's the last item
-%  if (!$CustomFields->IsLast) {
-%  $m->print(' | ') if $count > 1;
-    <a href="CustomFields.html?id=<%$id%>&CustomField=<%$CustomFieldObj->id%>&Move=1"><&|/l&>Move down</&></a>
-%  }
-</TD>
-</TR>
-% }
-
-</TABLE>
-% }
 <FORM METHOD=GET ACTION="CustomFields.html">
-% if ($id) {
-<INPUT TYPE="Hidden" NAME="id" VALUE="<%$id%>">
-% }
+<INPUT TYPE=HIDDEN NAME="id" VALUE="<% $Object->Id %>">
+<INPUT TYPE=HIDDEN NAME="ObjectType" VALUE="<% $ObjectType %>">
 <input type="checkbox" name="FindDisabledCustomFields"> <&|/l&>Include disabled custom fields in listing.</&>
 <input type=submit value="<&|/l&>Go!</&>">
 </FORM>
+<hr>
+<FORM ACTION="CustomFields.html" METHOD=POST>
+<INPUT TYPE=HIDDEN NAME="id" VALUE="<% $Object->Id %>">
+<INPUT TYPE=HIDDEN NAME="ObjectType" VALUE="<% $ObjectType %>">
+<INPUT TYPE=HIDDEN NAME="UpdateCFs" VALUE="1">
+
+% if ($Object->Id) {
+<h3>Global Custom Fields</h3>
+<& PickCustomFields, CustomFields => \@GlobalCFs, ReadOnly => 1 &>
+% }
+<h3>Associated Custom Fields (uncheck to unassociate)</h3>
+<& PickCustomFields, CustomFields => \@AssociatedCFs, id => $Object->Id, Checked => 1 &>
+<h3>Unassociated Custom Fields (check to associate)</h3>
+<& PickCustomFields, CustomFields => \@UnassociatedCFs, id => $Object->Id &>
+
+<& /Elements/Submit &>
+</FORM>
 
 
 <%INIT>
 my $CustomFields = RT::CustomFields->new($session{'CurrentUser'});
-my $QueueObj = RT::Queue->new($session{'CurrentUser'});
 my $caption;
+my @results;
+my (@GlobalCFs, @AssociatedCFs, @UnassociatedCFs);
 
-if ($id)  {
-        $QueueObj->Load($id);                        
-}
-
-if ($QueueObj->id) {
-	$CustomFields->LimitToQueue($id);
-}                                            
-else {                                       
-        $CustomFields->LimitToGlobal();
-}                                           
+# XXX - exception: by "RT::Queue" fields on UI we really mean "RT::Ticket" fields.
+my $composite = "$ObjectType--";
+$composite = 'RT::Ticket--RT::Queue' if $composite eq 'RT::Queue--';
+$CustomFields->LimitToComposite($composite);
 
 if ($FindDisabledCustomFields) {
     $caption = loc("All Custom Fields");
@@ -138,76 +112,60 @@
 }
 # }}}
 
-# {{{ now process the 'copy queue' action
-my @actions;
-if ($Source and $Source ne $id) {
-    my $SourceQueue = RT::Queue->new($session{'CurrentUser'});
-    $SourceQueue->Load($Source) || Abort(loc("Couldn't load queue"));
-    my $SourceCustomFields = RT::CustomFields->new($session{'CurrentUser'});
-    $SourceCustomFields->LimitToQueue($SourceQueue->id);
-
-    # delete old fields
-    foreach my $CustomFieldObj ( @{$CustomFields->ItemsArrayRef} ) { 
-	$CustomFieldObj->Delete;
-    }
-
-    # add new fields
-    while (my $SourceCustomFieldObj = $SourceCustomFields->Next) {
-	my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
-	my ($val, $msg) =  $CustomFieldObj->Create(
-	    id => $SourceCustomFieldObj->id,
-	    Queue => $id,
-	    Name => $SourceCustomFieldObj->Name,
-	    Type => $SourceCustomFieldObj->Type,
-	    Description => $SourceCustomFieldObj->Description,
-	);
-	Abort(loc("Could not create CustomField") . ": $msg") unless ($val);
-	push @actions, $msg;
-
-	$CustomFieldObj->SetSortOrder($SourceCustomFieldObj->SortOrder);
-
-	# add new values
-	my $values = $SourceCustomFieldObj->Values();
-	while (my $v = $values->Next) {
-	    my ( $addval, $addmsg ) = $CustomFieldObj->AddValue(
-		Name => $v->Name,
-		Description => $v->Description,
-		SortOrder => $v->SortOrder
-	    );
-	}
-    }
-
-    # because content changed, we must redo search for subsequent uses
-    $CustomFields->RedoSearch;
-    $CustomFields->GotoFirstItem;
+my $id = $Object->Id;
+my ($GlobalCFs, $ObjectCFs);
+$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
+$ObjectCFs->LimitToParentAndComposite(Parent => $Object, Composite => $composite);
+
+if ($id) {
+    $GlobalCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
+    $GlobalCFs->LimitToParentAndComposite(ParentType => ref($Object), Composite => $composite);
 }
-# }}}
 
-# {{{ deal with deleting existing custom fields
-foreach my $key (keys %ARGS) {
-  # {{{ if we're trying to delete the custom field
-  if ($key =~ /^DeleteCustomField-(\d+)/) {
-    my $id = $1;
-    my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
-    $CustomFieldObj->Load($id);
-    my ($retval, $msg) = $CustomFieldObj->Delete;
-    if ($retval) {
-      push @actions, loc("Custom field deleted");
+while (my $cf = $CustomFields->Next) { 
+    my $cf_id = $cf->Id;
+
+    if ($GlobalCFs and $GlobalCFs->HasEntryForCustomField($cf_id)) {
+	push @GlobalCFs, $cf;
+	next;
+    }
+
+    if ($UpdateCFs) {
+	# Go through and delete all the custom field relationships that this object
+	# no longer has
+	my $key = "Object-$id-CF-$cf_id";
+	if ($ARGS{$key}) {
+	    push @AssociatedCFs, $cf;
+	    if (!$ObjectCFs->HasEntryForCustomField($cf_id)) {
+		my ($val, $msg) = $cf->AddToParent($Object, $composite);
+		push (@results, $msg);
+	    }
+	    # my ($val, $msg) = $cf->SetSortOrderForObject(Object => $Object, SortOrder => $ARGS{"Object-$id-CF-$cf_id-SortOrder"});
+	}
+	else {
+	    push @UnassociatedCFs, $cf;
+	    if ($ObjectCFs->HasEntryForCustomField($cf_id)) {
+		my ($val, $msg) = $cf->RemoveFromParent($Object, $composite);
+		push (@results, $msg);
+	    }
+	}
+    }
+    elsif ($ObjectCFs->HasEntryForCustomField($cf_id)) {
+	push @AssociatedCFs, $cf;
     }
     else {
-      push @actions, $msg;
+	push @UnassociatedCFs, $cf;
     }
-  }
-  # }}}
 }
-# }}}
 
 </%INIT>
 <%ARGS>
-$id => 0
 $title => undef
 $Move => undef
 $Source => undef
 $CustomField => undef
 $FindDisabledCustomFields => undef
+$UpdateCFs => 0
+$Object
+$ObjectType
 </%ARGS>

Modified: rt/branches/autrijus-3.1/html/Admin/Elements/GroupTabs
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Elements/GroupTabs	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/GroupTabs	Thu Mar  4 10:50:03 2004
@@ -45,14 +45,18 @@
                path  => "Admin/Groups/GroupRights.html?id=" . $GroupObj->id, },
         G => { title => loc('User Rights'),
                path  => "Admin/Groups/UserRights.html?id=" . $GroupObj->id, },
+        H => { title => loc('History'),
+               path  => "Admin/Groups/History.html?id=" . $GroupObj->id },
     }
 }
 }
 $tabs->{"A"} = { title => loc('Select group'),
                  path  => "Admin/Groups/", };
 $tabs->{"B"} = { title     => loc('New group'),
-                 path      => "Admin/Groups/Modify.html?Create=1",
-                 separator => 1, };
+                 path      => "Admin/Groups/Modify.html?Create=1", };
+$tabs->{"C"} = { title => loc('Custom Fields'),
+		 path => "Admin/Groups/CustomFields.html",
+		 separator => 1, };
 
 # Now let callbacks add their extra tabs
 $m->comp( '/Elements/Callback', tabs => $tabs, %ARGS );

Added: rt/branches/autrijus-3.1/html/Admin/Elements/ObjectCustomFields
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/ObjectCustomFields	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,56 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title &>
+<& $ObjectTabs,
+$id ? (
+    id => $Object->id, 
+    current_tab => "Admin/$Types/CustomFields.html?id=".$id, 
+    current_subtab => "Admin/$Types/CustomFields.html?id=".$id, 
+    "${Type}Obj" => $Object,
+) : (
+    current_tab => "Admin/$Types/CustomFields.html",
+    current_subtab => "Admin/$Types/CustomFields.html",
+),
+    Title => $title
+    &>
+
+<& /Admin/Elements/EditCustomFields, title => $title, Object => $Object, %ARGS &>
+<%INIT>
+$ObjectType =~ /^RT::(Queue|User|Group)$/
+    or Abort(loc("Object of type [_1] cannot take custom fields", $ObjectType));
+
+my $Type = $1;
+my $Types = $Type.'s';
+my $ObjectTabs = "/Admin/Elements/${Type}Tabs";
+my $Object = $ObjectType->new($session{'CurrentUser'});
+$Object->Load($id) || Abort(loc("Couldn't load object [_1]", $id)) if $id;
+
+my $title = ($id ? loc('Edit Custom Fields for [_1]', $Object->Name)
+		 : loc("Modify Custom Fields which apply to all [_1]", loc($Types)));
+
+</%INIT>
+<%ARGS>
+$id => undef
+$ObjectType
+</%ARGS>

Modified: rt/branches/autrijus-3.1/html/Admin/Elements/QueueTabs
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Elements/QueueTabs	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/QueueTabs	Thu Mar  4 10:50:03 2004
@@ -68,6 +68,9 @@
 			   };
   $tabs->{"B"} = { title => loc('New queue'),
   		     	path => "Admin/Queues/Modify.html?Create=1",
+			   };
+  $tabs->{"C"} = { title => loc('Custom Fields'),
+  		     	path => "Admin/Queues/CustomFields.html",
 			separator => 1,
 			   };
 }

Added: rt/branches/autrijus-3.1/html/Admin/Elements/SelectCustomFieldObjectType
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/SelectCustomFieldObjectType	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,36 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<SELECT NAME ="<%$Name%>">
+%for my $option ($cf->ObjectTypeComposites) {
+<OPTION VALUE="<%$option%>" <%$option eq $Default && "SELECTED"%>><% $cf->FriendlyObjectTypeComposite($option) %></OPTION>
+%}
+</SELECT>
+<%INIT>
+my $cf = RT::CustomField->new($session{'CurrentUser'});
+
+</%INIT>
+<%ARGS>
+$Default=>undef
+$Name => 'ObjectTypeComposite'
+</%ARGS>

Modified: rt/branches/autrijus-3.1/html/Admin/Elements/SelectCustomFieldType
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Elements/SelectCustomFieldType	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/SelectCustomFieldType	Thu Mar  4 10:50:03 2004
@@ -22,8 +22,8 @@
 %# 
 %# END LICENSE BLOCK
 <SELECT NAME ="<%$Name%>">
-%for my $option ($cf->Types) {
-<OPTION VALUE="<%$option%>" <%$option eq $Default && "SELECTED"%>><% $cf->FriendlyType($option) %></OPTION>
+%for my $option ($cf->TypeComposites) {
+<OPTION VALUE="<%$option%>" <%$option eq $Default && "SELECTED"%>><% $cf->FriendlyTypeComposite($option) %></OPTION>
 %}
 </SELECT>
 <%INIT>
@@ -32,5 +32,5 @@
 </%INIT>
 <%ARGS>
 $Default=>undef
-$Name => 'Type'
+$Name => 'TypeComposite'
 </%ARGS>

Modified: rt/branches/autrijus-3.1/html/Admin/Elements/SelectRights
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Elements/SelectRights	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/SelectRights	Thu Mar  4 10:50:03 2004
@@ -78,7 +78,7 @@
     } 
 
         else {
-                %Rights = { loc('System Error') => loc("No rights found")};
+                %Rights = ( loc('System Error') => loc("No rights found") );
         }
         
     $ACLDesc = "$PrincipalId-".ref($Object)."-".$Object->Id;

Modified: rt/branches/autrijus-3.1/html/Admin/Elements/SystemTabs
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Elements/SystemTabs	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/SystemTabs	Thu Mar  4 10:50:03 2004
@@ -36,9 +36,9 @@
                         path => 'Admin/Global/Templates.html',
                       },
               
-                F => { title => loc('Custom Fields'),
-                        path => 'Admin/Global/CustomFields.html',
-                        },
+#                F => { title => loc('Custom Fields'),
+#                        path => 'Admin/Global/CustomFields.html',
+#                        },
 
                 G => { title => loc('Group Rights'),
                                 path => 'Admin/Global/GroupRights.html',

Modified: rt/branches/autrijus-3.1/html/Admin/Elements/Tabs
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Elements/Tabs	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/Tabs	Thu Mar  4 10:50:03 2004
@@ -37,8 +37,14 @@
 	       C => { title => loc('Queues'),
 			   path => 'Admin/Queues/',
 			 },
-	       D => { 'title' => loc('Global'),
+	       D => { 'title' => loc('Custom Fields'),
+			   path => 'Admin/CustomFields/',
+			 },
+	       E => { 'title' => loc('Global'),
 			   path => 'Admin/Global/',
+			 },
+	       F => { 'title' => loc('Tools'),
+			   path => 'Admin/Tools/',
 			 },
 	     };
 

Modified: rt/branches/autrijus-3.1/html/Admin/Elements/UserTabs
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Elements/UserTabs	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Elements/UserTabs	Thu Mar  4 10:50:03 2004
@@ -34,9 +34,12 @@
 
 			   path => "Admin/Users/Modify.html?id=".$id,
 subtabs => {
-	       Queues => { title => loc('Basics'),
+	       Basics => { title => loc('Basics'),
 			   path => "Admin/Users/Modify.html?id=".$id
 			 },
+	       History => { title => loc('History'),
+			   path => "Admin/Users/History.html?id=".$id
+			 },
 #	       Scrips => { title => loc('Rights'),
 #			   path => "Admin/Users/Rights.html?id=".$id
 #			 }
@@ -50,6 +53,9 @@
 			   };
   $tabs->{"B"} = { title => loc('New user'),
   		     	path => "Admin/Users/Modify.html?Create=1",
+			   };
+  $tabs->{"C"} = { title => loc('Custom Fields'),
+  		     	path => "Admin/Users/CustomFields.html",
 			separator => 1,
 			   };
 }

Modified: rt/branches/autrijus-3.1/html/Admin/Global/index.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Global/index.html	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Global/index.html	Thu Mar  4 10:50:03 2004
@@ -46,10 +46,10 @@
                         path => 'Templates.html',
                       },
               
-                F => { title => loc('Custom Fields'),
-                        text => loc('Modify Custom Fields which apply to all queues'),
-                        path => 'CustomFields.html',
-                        },
+#                F => { title => loc('Custom Fields'),
+#                        text => loc('Modify Custom Fields which apply to all queues'),
+#                        path => 'CustomFields.html',
+#                        },
 
                 G => { title => loc('Group Rights'),
                                 text => loc('Modify global group rights'),

Added: rt/branches/autrijus-3.1/html/Admin/Groups/History.html
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/Groups/History.html	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,44 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title  &>
+<& /Admin/Elements/GroupTabs, 
+    id => $id, 
+    GroupObj => $GroupObj,
+    current_subtab => $current_tab, 
+    Title => $title &>
+
+<& /Ticket/Elements/ShowHistory,
+    Ticket => $GroupObj,
+    ShowHeaderModes => 0,
+&>
+
+<%INIT>
+my $current_tab = 'Admin/Groups/History.html?id='.$id;
+my $GroupObj = new RT::Group($session{'CurrentUser'});
+$GroupObj->Load($id) || Abort("Couldn't load group '$id'");
+my $title = loc("History of the group [_1]", $GroupObj->Name);
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>

Modified: rt/branches/autrijus-3.1/html/Admin/Groups/Modify.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Groups/Modify.html	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Groups/Modify.html	Thu Mar  4 10:50:03 2004
@@ -43,10 +43,20 @@
 <&|/l&>Name</&>:
 </TD>
 <TD><INPUT name="Name" value="<%$Group->Name%>"></TD>
-</TR><TR>
+</TR>
+<TR>
 <TD ALIGN=RIGHT>
 <&|/l&>Description</&>:</TD><TD COLSPAN=3><INPUT name="Description" value="<%$Group->Description%>" size=60></TD>
-</TR><TR>
+</TR>
+% my $CFs = $Group->CustomFields;
+% while (my $CF = $CFs->Next) {
+<TR><TD ALIGN="RIGHT">
+<% $CF->Name %>
+</TD><TD>
+<& /Ticket/Elements/EditCustomField, CustomField => $CF &>
+</TD></TR>
+% }
+<TR>
 <TD COLSPAN=2>
 <INPUT TYPE=HIDDEN NAME="SetEnabled" VALUE="1">
 <INPUT TYPE=CHECKBOX NAME="Enabled" VALUE="1" <%$EnabledChecked%>> <&|/l&>Enabled (Unchecking this box disables this group)</&><BR>

Modified: rt/branches/autrijus-3.1/html/Admin/Queues/CustomField.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Queues/CustomField.html	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Queues/CustomField.html	Thu Mar  4 10:50:03 2004
@@ -56,5 +56,5 @@
 </%INIT>
 <%ARGS>
 $CustomField => undef
-$Queue => undef
+$Queue => 0
 </%ARGS>

Modified: rt/branches/autrijus-3.1/html/Admin/Queues/CustomFields.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Queues/CustomFields.html	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Queues/CustomFields.html	Thu Mar  4 10:50:03 2004
@@ -21,29 +21,4 @@
 %# 
 %# 
 %# END LICENSE BLOCK
-<& /Admin/Elements/Header, Title => $title &>
-<& /Admin/Elements/QueueTabs, id => $Queue->id, 
-    current_tab => 'Admin/Queues/CustomFields.html?id='.$id, 
-    QueueObj => $Queue,                                                      
-    subtabs => $subtabs,
-    Title => $title
-    &>
-
-<& /Admin/Elements/EditCustomFields, title => $title, %ARGS &>
-<%INIT>
-my $Queue = new RT::Queue($session{'CurrentUser'});
-$Queue->Load($id) || Abort(loc("Couldn't load queue", $id));
-
-my $CustomFields = RT::CustomFields->new($RT::SystemUser);
-$CustomFields->LimitToQueue($Queue->Id);
-my $subtabs = {
-	 A => { title => loc('New custom field'),
-	     	path => "Admin/Queues/CustomField.html?create=1&Queue=".$id,
-			   }
-	      };
-
-my $title=  loc('Edit Custom Fields for [_1]', $Queue->Name);
-</%INIT>
-<%ARGS>
-$id => undef
-</%ARGS>
+<& /Admin/Elements/ObjectCustomFields, %ARGS, ObjectType => 'RT::Queue' &>

Modified: rt/branches/autrijus-3.1/html/Admin/Queues/Modify.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Queues/Modify.html	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Queues/Modify.html	Thu Mar  4 10:50:03 2004
@@ -21,11 +21,11 @@
 %# 
 %# 
 %# END LICENSE BLOCK
-<& /Admin/Elements/Header, Title => loc('Admin/Queue/Basics') &>
+<& /Admin/Elements/Header, Title => $title &>
 <& /Admin/Elements/QueueTabs, id => $QueueObj->id, 
     QueueObj => $QueueObj,
     current_tab => $current_tab, 
-    Title => loc('Admin/Queue/Basics') &>
+    Title => $title &>
 <& /Elements/ListActions, actions => \@results &>
 
 
@@ -137,7 +137,7 @@
   }
   if  ( ($SetEnabled) and ( $Disabled != $QueueObj->Disabled) ) { 
       my  ($code, $msg) = $QueueObj->SetDisabled($Disabled);
-      push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+      push @results, loc('Enabled status: [_1]', loc_fuzzy($msg));
   }
   
   if ($QueueObj->Disabled()) {

Added: rt/branches/autrijus-3.1/html/Admin/Users/CustomFields.html
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/Users/CustomFields.html	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,24 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/ObjectCustomFields, %ARGS, ObjectType => 'RT::User' &>

Added: rt/branches/autrijus-3.1/html/Admin/Users/History.html
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/html/Admin/Users/History.html	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,44 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work 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.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<& /Admin/Elements/Header, Title => $title  &>
+<& /Admin/Elements/UserTabs, 
+    id => $id, 
+    UserObj => $UserObj,
+    current_subtab => $current_tab, 
+    Title => $title &>
+
+<& /Ticket/Elements/ShowHistory,
+    Ticket => $UserObj,
+    ShowHeaderModes => 0,
+&>
+
+<%INIT>
+my $current_tab = 'Admin/Users/History.html?id='.$id;
+my $UserObj = new RT::User($session{'CurrentUser'});
+$UserObj->Load($id) || Abort("Couldn't load user '$id'");
+my $title = loc("History of the user [_1]", $UserObj->Name);
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>

Modified: rt/branches/autrijus-3.1/html/Admin/Users/Modify.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/Users/Modify.html	(original)
+++ rt/branches/autrijus-3.1/html/Admin/Users/Modify.html	Thu Mar  4 10:50:03 2004
@@ -179,6 +179,20 @@
 <TR>
 </TR>
 </TABLE>
+<& /Elements/TitleBoxStart, title => loc('Custom Fields') &>
+<TABLE>
+% my $CFs = $UserObj->CustomFields;
+% while (my $CF = $CFs->Next) {
+<TR><TD ALIGN="RIGHT">
+<% $CF->Name %>
+</TD><TD>
+<& /Ticket/Elements/EditCustomField, CustomField => $CF &>
+</TD></TR>
+% }
+<TR>
+</TR>
+</TABLE>
+<& /Elements/TitleBoxEnd &>
 <TR>
 <TD colspan="2">
 <& /Elements/TitleBoxStart, title => loc('Comments about this user') &>

Modified: rt/branches/autrijus-3.1/html/Admin/index.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Admin/index.html	(original)
+++ rt/branches/autrijus-3.1/html/Admin/index.html	Thu Mar  4 10:50:03 2004
@@ -34,6 +34,9 @@
 <li><font size="+2"><a href="Queues/"><&|/l&>Queues</&></a></font><br>
 <&|/l&>Manage queues and queue-specific properties</&>
 </li>
+<li><font size="+2"><a href="CustomFields/"><&|/l&>Custom Fields</&></a></font><br>
+<&|/l&>Manage custom fields and custom field values</&>
+</li>
 <li><font size="+2"><a href="Global/"><&|/l&>Global</&></a></font><br>
 <&|/l&>Manage properties and configuration which apply to all queues</&>
 </li>

Modified: rt/branches/autrijus-3.1/html/Elements/Callback
==============================================================================
--- rt/branches/autrijus-3.1/html/Elements/Callback	(original)
+++ rt/branches/autrijus-3.1/html/Elements/Callback	Thu Mar  4 10:50:03 2004
@@ -54,10 +54,11 @@
     $cache{$Page,$_CallbackName} = $callbacks;
 }
 
+my @rv;
 foreach my $comp (sort @$callbacks) {
-        $m->comp($comp, %ARGS) if $m->comp_exists($comp);
+        push @rv, $m->comp($comp, %ARGS) if $m->comp_exists($comp);
 }
-return(1);
+return @rv;
 </%init>
 <%args>
 $_CallbackName => 'Default'

Modified: rt/branches/autrijus-3.1/html/Elements/MyRequests
==============================================================================
--- rt/branches/autrijus-3.1/html/Elements/MyRequests	(original)
+++ rt/branches/autrijus-3.1/html/Elements/MyRequests	Thu Mar  4 10:50:03 2004
@@ -21,11 +21,15 @@
 %# 
 %# 
 %# END LICENSE BLOCK
-<&|/Elements/TitleBox, title => loc('[_1] highest priority tickets I requested', $rows) &>
+<&|/Elements/TitleBox, 
+        title => loc("[_1] newest unowned tickets...", $rows) &>
 <& /Elements/TicketList, 
-        Title => loc("[_1] highest priority tickets I requested...", $rows),
-        Format => "'<a href=\"/Ticket/Display.html?id=__id__\">__id__</a>/TITLE:#', '<a href=\"/Ticket/Display.html?id=__id__\">__Subject__</a>/TITLE:Subject', QueueName, ExtendedStatus, OwnerName",
-        Query => "Requestor = '".$session{'CurrentUser'}->EmailAddress."' AND ( Status = 'new' OR Status = 'open')",
+        Format => "'<a href=\"$RT::WebPath/Ticket/Display.html?id=__id__\">__id__</a>/TITLE:#', '<a href=\"$RT::WebPath/Ticket/Display.html?id=__id__\">__Subject__</a>/TITLE:Subject', QueueName, ExtendedStatus, CreatedRelative, '<A HREF=\"$RT::WebPath/Ticket/Display.html?Action=Take&id=__id__\">".loc('Take')."</a>/TITLE:&nbsp;' ",
+        Query => "Owner = 'Nobody' AND ( Status = 'new' OR Status = 'open')",
+        OrderBy => 'Created',
+        Order => 'DESC',
+        ShowNavigation => 0,
+        Rows => $rows
 
         &>
 </&>

Modified: rt/branches/autrijus-3.1/html/Elements/MyTickets
==============================================================================
--- rt/branches/autrijus-3.1/html/Elements/MyTickets	(original)
+++ rt/branches/autrijus-3.1/html/Elements/MyTickets	Thu Mar  4 10:50:03 2004
@@ -24,12 +24,13 @@
 <&|/Elements/TitleBox, title => loc('[_1] highest priority tickets I own', $rows) &>
 <& /Elements/TicketList, 
         Title => loc("[_1] highest priority tickets I requested...", $rows),
-        Format => "'<a href=\"/Ticket/Display.html?id=__id__\">__id__</a>/TITLE:#', '<a href=\"/Ticket/Display.html?id=__id__\">__Subject__</a>/TITLE:Subject', QueueName, ExtendedStatus",
+        Format => "'<a href=\"$RT::WebPath/Ticket/Display.html?id=__id__\">__id__</a>/TITLE:#', '<a href=\"$RT::WebPath/Ticket/Display.html?id=__id__\">__Subject__</a>/TITLE:Subject', Priority, QueueName, ExtendedStatus",
 
-        Query => " Owner = '".$session{'CurrentUser'}->Id."' AND ( Status = 'new' OR Status = 'open')",
+        Query => " Owner = '".$session{'CurrentUser'}->Id."' AND ( Status = 'new' OR Status = 'open') AND Priority > 0",
         OrderBy => 'Priority',
         Order => 'DESC',
-        Rows => $rows
+        Rows => $rows,
+        ShowNavigation => 0
         &>
 </&> 
 <%init>

Modified: rt/branches/autrijus-3.1/html/Elements/SetupSessionCookie
==============================================================================
--- rt/branches/autrijus-3.1/html/Elements/SetupSessionCookie	(original)
+++ rt/branches/autrijus-3.1/html/Elements/SetupSessionCookie	Thu Mar  4 10:50:03 2004
@@ -78,10 +78,6 @@
 
     } 
 
-    # since If-Modified-Since makes no sense for RT, we explicitly kills cache
-    $r->header_out('Pragma' => 'no-cache');
-    $r->header_out('Cache-control' => 'no-cache, no-store');
-
     return();
 </%init>
 <%args>

Modified: rt/branches/autrijus-3.1/html/Elements/TicketList
==============================================================================
--- rt/branches/autrijus-3.1/html/Elements/TicketList	(original)
+++ rt/branches/autrijus-3.1/html/Elements/TicketList	Thu Mar  4 10:50:03 2004
@@ -28,6 +28,9 @@
     map => $map, 
     AllowSorting => $AllowSorting, 
     Order => $Order, 
+    Query => $Query,
+    Rows => $Rows,
+    Page => $Page,
     OrderBy => $OrderBy , 
     BaseURL => $BaseURL  &> 
 % my $i;
@@ -36,7 +39,7 @@
 <& .Row, Format => \@Format, i => $i, record => $record, map => $map &>
 % }
 </TABLE>
-
+% if ($ShowNavigation) {
 <&|/l, $Page, int($TotalFound/$Rows)&>Page [_1] of [_2]</&>
 % if ($Page != 1) {
 <A href="<%$BaseURL%>?Page=<%$Page-1%>&Rows=<%$Rows%>&Format=<%$Format%>&Query=<%$Query%>"><&|/l&>Previous Page</&></a>
@@ -44,11 +47,11 @@
 % if (($Page * $Rows) < $TotalFound) {
 <A href="<%$BaseURL%>Page=<%$Page+1%>&Rows=<%$Rows%>&Format=<%$Format%>&Query=<%$Query%>"><&|/l&>Next Page</&></a>
 % }
-
-
-
+% }
 <%INIT>
 
+$Format = $RT::DefaultSearchResultFormat unless $Format;
+
 $Rows = '25' unless ($Rows); # we need a positive value
 # {{{ item map
 my $map = {
@@ -219,6 +222,7 @@
 $OrderBy => undef
 $BaseURL => undef
 $Format => $RT::DefaultSearchResultFormat
+$ShowNavigation => 1
 </%ARGS>
 %#### SUB COMPONENTS
 %#
@@ -231,9 +235,14 @@
 $AllowSorting => undef
 $Order=>undef
 $BaseURL => undef
+$Query => undef
+$Rows => undef
+$Page => undef
 </%ARGS>
 <TR>
 <%perl>
+my @generic_query_args = ( 'Query=' . $Query, 'Rows=' . $Rows, 'Page=' . $Page );
+
 foreach my $col (@Format) {
     if ( $col->{title} eq 'NEWLINE' ) {
         $m->out('</TR>       <TR>');
@@ -244,7 +253,7 @@
         $title =~ s/^__(.*)__$/$1/o;
         $title = ( $map->{$title}->{title} || $title );
         if ( $AllowSorting && $col->{'attribute'} ) {
-            my @query_args;
+            my @query_args = @generic_query_args;
             push @query_args,
               ( "OrderBy="
               . ( $map->{ $col->{'attribute'} }->{'attribute'}

Modified: rt/branches/autrijus-3.1/html/NoAuth/webrt.css
==============================================================================
--- rt/branches/autrijus-3.1/html/NoAuth/webrt.css	(original)
+++ rt/branches/autrijus-3.1/html/NoAuth/webrt.css	Thu Mar  4 10:50:03 2004
@@ -331,7 +331,9 @@
 	margin-bottom:0;
 }
 
-
+<%flags>
+inherit => undef
+</%flags>
 <%init>
 $r->content_type('text/css');
 $r->header_out('Expires' ,'+30m');

Modified: rt/branches/autrijus-3.1/html/Projects/Elements/OverviewEntry
==============================================================================
--- rt/branches/autrijus-3.1/html/Projects/Elements/OverviewEntry	(original)
+++ rt/branches/autrijus-3.1/html/Projects/Elements/OverviewEntry	Thu Mar  4 10:50:03 2004
@@ -1,40 +1,78 @@
 % if ($Root) {
+% if ($ARGS{'Edit-'.$Root->Id})  {
+% my $Parent;
+%if ($Root->MemberOf->First && $Root->MemberOf->First->TargetObj) {
+%        $Parent = $Root->MemberOf->First->TargetObj->Id;
+%} else {
+%        $Parent = undef;
+%}
 <TR>
-<TD><tt><% "&nbsp;"x $Depth|n %></tt><A HREF="Edit.html?Project=<%$Project%>&id=<%$Root->Id%>" onClick="window.open('Edit.html?Project=<%$Project%>&id=<%$Root->Id%>','edit','toolbar=no,width=600,height=450,left=10,top=10,screenX=10,screenY=10,status=no,scrollbars=yes,resizable=1');return false"><%$Root->Subject%></A></TD>
+<TD><% "&nbsp;"x $Depth|n %><input name="Ticket-<%$Root->id%>-Subject" value="<%$Root->Subject%>" size="25"><br>
+%#<&|/l&>Move</&>:<& SelectProjectTask, Name=> 'Ticket-'.$Root->id."-Parent", Project => $Project, Default =>  $Parent &>
+</TD>
+<TD><& /Elements/SelectOwner, Name => 'Ticket-'.$Root->id.'-Owner', Default => $Root->OwnerObj->id &></TD>
+<TD><& /Elements/SelectStatus, Name => 'Ticket-'.$Root->id.'-Status', Default => $Root->Status &></TD>
+<TD><input name="Ticket-<%$Root->id%>-Due" value ="<%$Root->Due%>" size=10></TD>
+<TD><input name="Ticket-<%$Root->id%>-Priority" value="<%$Root->Priority%>" size=2></TD>
+<TD><input name="Ticket-<%$Root->id%>-TimeWorked" value="<%$Root->TimeWorked%>" size="3"></TD>
+<TD><input name="Ticket-<%$Root->id%>-TimeLeft" value="<%$Root->TimeLeft%>" size="3"></TD>
+<TD><input type="submit"  value="<%loc('Save')%>"></TD>
+</TR>
+% }
+% else {
+
+<TR>
+<TD><tt><% "&nbsp;"x $Depth|n %></tt><A HREF="<%$RT::WebPath%>/Ticket/Display.html?id=<%$Root->id%>" target="_newwin"><%$Root->Subject%></A></TD>
 <TD><%$Root->OwnerObj->Name%></TD>
+<TD><%$Root->Status%></TD>
 <TD><%$Root->DueObj->AgeAsString%></TD>
 <TD><%$Root->Priority%></TD>
 <TD><%int($Root->TimeWorked/6)/10%></TD>
 <TD><%int($Root->TimeLeft/6)/10%></TD>
-<TD align=right><font size=-2>
-<DIV ALIGN=RIGHT>[<A HREF="Create.html?Queue=<%$Root->Queue%>&Parent=<%$Root->Id%>&Owner=<%$Root->Owner%>&Project=<%$Project%>" onClick="window.open('Create.html?Queue=<%$Root->Queue%>&Parent=<%$Root->Id%>&Owner=<%$Root->Owner%>&Project=<%$Project%>','wdyt','toolbar=no,width=500,height=450,left=10,top=10,screenX=30,screenY=30,status=no,scrollbars=yes,resizable=1');return false">New subtask</A>]</DIV></font>
+<TD align=right>
+<input type="submit" name="AddChildOf-<%$Root->Id%>" value="+">
+<input type="submit" name="Edit-<%$Root->Id%>" value="<%loc('Edit')%>">
+</td>
+</TR>
+% }
 
-% if ($Root->Id == $AddChildOf) {
+% if ($Depth < $MaxDepth) {
+% while (my $link = $tasks->Next()) {
+<& OverviewEntry, %ARGS, Root=> $link, Depth => ($Depth+1), MaxDepth => $MaxDepth, Project => $Project &>
+% }
+
+% }
+
+% if ($ARGS{"AddChildOf-".$Root->Id}) {
 <TR>
-<TD><form method="post"><% "&nbsp;"x $Depth|n %><input name="Subject" size="25"></TD>
-<TD><& /Elements/SelectOwner, Name => 'Owner' &></TD>
+<TD><% "&nbsp;"x $Depth|n %><input name="Subject" size="25">
+
+<input type="hidden" name="new-MemberOf" value="<%$Root->id%>">
+<input type="hidden" name="AddChildOf<%$Root->id%>" value="1">
+</TD>
+
+<TD><& /Elements/SelectOwner, Name => 'Owner', Default => $RT::Nobody->id &></TD>
+<TD><& /Elements/SelectStatus, Name => 'Status', Default => 'new' &></TD>
 <TD><input name="Due" size=10></TD>
 <TD><input name="Priority" size=2></TD>
 <TD><input name="TimeWorked" size="3"></TD>
 <TD><input name="TimeLeft" size="3"></TD>
-<TD><input type="submit"></form</TD>
+<TD><input type="submit" name="CreateTask" value="<%loc('Create')%>"></TD>
+</TR>
 %}
 
-% if ($Depth < $MaxDepth) {
-% while (my $link = $tasks->Next()) {
-<& OverviewEntry, Root=> $link->BaseObj, Depth => ($Depth+1), MaxDepth => $MaxDepth, Project => $Project &>
-% }
-
-% }
 % }
 <%ARGS>
 $Depth => 0
 $MaxDepth => 8
 $Root => undef
 $Project => undef
-$AddChildOf => undef
+$Edit => undef
+$EditAll => 0
 </%ARGS>
 
 <%INIT>
-my $tasks = $Root->Members();
+
+my $tasks = RT::Tickets->new($session{'CurrentUser'});
+$tasks->FromSQL('MemberOf = '.$Root->id);
 </%INIT>

Modified: rt/branches/autrijus-3.1/html/Projects/Elements/SelectProjectTaskEntry
==============================================================================
--- rt/branches/autrijus-3.1/html/Projects/Elements/SelectProjectTaskEntry	(original)
+++ rt/branches/autrijus-3.1/html/Projects/Elements/SelectProjectTaskEntry	Thu Mar  4 10:50:03 2004
@@ -7,7 +7,7 @@
 </OPTION>
 %# if ($Depth < $MaxDepth) {
 % while (my $link = $tasks->Next()) {
-<& SelectProjectTaskEntry, Root=> $link->BaseObj, Depth => ($Depth+1), MaxDepth => $MaxDepth, Project => $Project, Default => $Default &>
+<& SelectProjectTaskEntry, Root=> $link, Depth => ($Depth+1), MaxDepth => $MaxDepth, Project => $Project, Default => $Default &>
 % }
 %# }
 % }
@@ -20,5 +20,6 @@
 </%ARGS>
 
 <%INIT>
-my $tasks = $Root->Members();
+my $tasks = RT::Tickets->new($session{'CurrentUser'});
+$tasks->FromSQL('MemberOf = '. $Root->id);
 </%INIT>

Modified: rt/branches/autrijus-3.1/html/Projects/Overview.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Projects/Overview.html	(original)
+++ rt/branches/autrijus-3.1/html/Projects/Overview.html	Thu Mar  4 10:50:03 2004
@@ -1,13 +1,21 @@
 <& /Elements/Header, Title => $ProjectObj->Subject . " / Project Overview" &> 
 <& Elements/Tabs, Ticket => $ProjectObj, current_tab => 'Projects/Overview.html?id='.$ProjectObj->Id &>
+
+<& /Elements/ListActions, actions => \@messages &>
+
+<form method="post" action="Overview.html">
+<input type="hidden" name="Project" value="<%$Project%>">
+<input type="hidden" name="id" value="<%$id%>">
+
 <TABLE WIDTH=100% CELLSPACING=0 BORDER=0 CELLPADDING=2>
 <TR BGCOLOR="#993333">
-<TD CLASS=INVERSE>Task</TD>
-<TD CLASS=INVERSE>Owner</TD>	
-<TD CLASS=INVERSE>Due</TD>
-<TD CLASS=INVERSE>Priority</TD>
-<TD CLASS=INVERSE>Worked</TD>
-<TD CLASS=INVERSE>Left</TD>
+<TD CLASS=INVERSE><&|/l&>Task</&></TD>
+<TD CLASS=INVERSE><&|/l&>Owner</&></TD>	
+<TD CLASS=INVERSE><&|/l&>Status</&></TD>	
+<TD CLASS=INVERSE><&|/l&>Due</&></TD>
+<TD CLASS=INVERSE><&|/l&>Priority</&></TD>
+<TD CLASS=INVERSE><&|/l&>Estimate</&></TD>
+<TD CLASS=INVERSE><&|/l&>Left</&></TD>
 <TD>&nbsp;</TD>
 </TR>
 % my $parents = $task->MemberOf;
@@ -17,27 +25,57 @@
 % } else {
 <TR><TD colspan=7 BGCOLOR="#cccccc"><a HREF="Overview.html?Project=<%$Project%>&id=<%$link->TargetObj->Id%>">Up</A></TD></TR>
 % }
-<& Elements/OverviewEntry, Root=> $link->TargetObj, Depth => 0, MaxDepth => 0,
-Project => $Project, AddChildOf => $AddChildOf &>
+<& Elements/OverviewEntry, 
+    Root=> $link->TargetObj, 
+    Depth => 0, 
+    MaxDepth => 0,
+    Project => $Project,
+    %ARGS &>
 % }
 % unless ($task->MemberOf->First) {
 <TR><TD colspan=7 BGCOLOR="#cccccc">Top</TD></TR>
 % }
-<& Elements/OverviewEntry, Root=> $task, Depth => 1, Project => $Project,
-AddChildOf => $AddChildOf &>
-</TABLE>
-</BODY>
-</HTML>
+<& Elements/OverviewEntry, 
+    Root=> $task, 
+    Depth => 1, 
+    Project => $Project,
+    %ARGS
+    &>
+
+</FORM>
 <%INIT>
+my (@messages);
+my @tix_to_update;
 
+ grep { /^Ticket-(\d+)-/ && push @tix_to_update, $1 } (keys %ARGS);
+foreach my $ticket_id (@tix_to_update) {
+    my $ticket=    LoadTicket($ticket_id);
+    my %ticket_args;
+    grep { /^Ticket-$ticket_id-(.*)$/ && ($ticket_args{$1} = $ARGS{$_})} (keys %ARGS);
+    ProcessTicketDates ( TicketObj =>$ticket, ARGSRef => \%ticket_args);
+    ProcessTicketBasics ( TicketObj =>$ticket, ARGSRef => \%ticket_args);
+}
 
 my $task = LoadTicket($id);
 $Project = $task->Id unless ($Project); 
 my $ProjectObj = LoadTicket($Project);
+
+
+
+if ($ARGS{'CreateTask'}) {
+   
+    $ARGS{'Queue'} = $task->QueueObj->id;
+my     ($new_id, $new_msg) = CreateTicket(%ARGS);
+push (@messages, $new_msg);
+}
+
+
+
+
 </%INIT>
 
 <%ARGS>
-$id => undef
 $Project => undef
 $AddChildOf => undef
+$id => undef
 </%ARGS>

Modified: rt/branches/autrijus-3.1/html/Search/Build.html
==============================================================================
--- rt/branches/autrijus-3.1/html/Search/Build.html	(original)
+++ rt/branches/autrijus-3.1/html/Search/Build.html	Thu Mar  4 10:50:03 2004
@@ -80,6 +80,8 @@
 my %queues;
 
 if ( $ARGS{"DoSearch"} ) {
+    $Format =~ s/%23/#/g;
+    $Format =~ s/%26/&/g;
     $m->comp( "Results.html", Query   => $Query, Format  => $Format, OrderBy => $ARGS{OrderBy}, Rows    => $ARGS{RowsPerPage});
     $m->abort();
 }
@@ -340,9 +342,7 @@
     my $selected;
 
     next unless ( $val->{Value}->{Key} || $val->{Value}->{Subkey} );
-    if ( exists $val->{Value}->{EA} && $val->{Value}->{EA} ne "" ) {
-        $ea = $val->{Value}->{EA};
-    }
+    $ea = $val->{EA};
 
     if ( $depth > 0 ) {
         if ( $key eq $currentkey ) {
@@ -378,10 +378,6 @@
         my $j = 0;
         while ( my $item = $items->{ $i + ( $j / 10 ) } ) {
 
-            if ( !$ea ) {
-                $ea = $item->{EA};
-            }
-
             my $depth = $i;
 
             my $subkey = $item->{Subkey};
@@ -393,11 +389,12 @@
                 else {
                     $sendkey = "{$i.$j}";
                 }
-                push @$keys, { Key => $sendkey, Value => $item };
+                push @$keys, { Key => $sendkey, Value => $item, EA => $ea };
                 $$Query .= " " . $ea . " " if ( $j > 0 );
                 $$Query .= "("             if $depth > 0;
                 my $x = $i + 1;
-                build_array( $Query, $subkey, $sendkey, $ea, $x, $keys, , $queues );
+                build_array( $Query, $subkey, $sendkey, $item->{EA}, 
+			     $x, $keys, , $queues );
                 $$Query .= ")" if $depth > 0;
             }
             else {
@@ -411,7 +408,7 @@
                     }
                     $$Query .= " " . $ea . " " if ( $j > 0 );
                     $$Query .= "$item->{Key} $item->{Op} $item->{Value}";
-                    push @$keys, { Key => $mykey, Value => $item };
+                    push @$keys, { Key => $mykey, Value => $item, EA => $ea };
 
                     if ( $item->{Key} eq "Queue" ) {
                         $queues->{ $item->{Value} } = 1;

Modified: rt/branches/autrijus-3.1/html/Search/Elements/PickRestriction
==============================================================================
--- rt/branches/autrijus-3.1/html/Search/Elements/PickRestriction	(original)
+++ rt/branches/autrijus-3.1/html/Search/Elements/PickRestriction	Thu Mar  4 10:50:03 2004
@@ -35,7 +35,7 @@
 
 <li>
 <& /Elements/SelectWatcherType, Name => "WatcherRole", AllowNull => 0 &>
-<&|/l&> email address</&> 
+<&|/l&>email address</&> 
 <& /Elements/SelectMatch, Name => "WatcherRoleOp" &>
 <INPUT Name="ValueOfWatcherRole" SIZE=20>
 

Modified: rt/branches/autrijus-3.1/html/Ticket/Attachment/dhandler
==============================================================================
--- rt/branches/autrijus-3.1/html/Ticket/Attachment/dhandler	(original)
+++ rt/branches/autrijus-3.1/html/Ticket/Attachment/dhandler	Thu Mar  4 10:50:03 2004
@@ -65,4 +65,6 @@
      $m->out($AttachmentObj->OriginalContent);
      $m->abort; 
 </%perl>
-
+<%attr>
+AutoFlush => 0
+</%attr>

Modified: rt/branches/autrijus-3.1/html/Ticket/Elements/ShowAttachments
==============================================================================
--- rt/branches/autrijus-3.1/html/Ticket/Elements/ShowAttachments	(original)
+++ rt/branches/autrijus-3.1/html/Ticket/Elements/ShowAttachments	Thu Mar  4 10:50:03 2004
@@ -63,6 +63,9 @@
 my $transactions = $Ticket->Transactions();
 while (my $trans = $transactions->Next()) {
         my $attachments = $trans->Attachments();
+	$attachments->Columns( qw( Id Filename ContentType Headers Subject Parent ContentEncoding ContentType TransactionId) );
+        $attachments->Limit(FIELD => 'Filename', OPERATOR => 'IS NOT', VALUE => 'NULL', QUOTEVALUE => 0, ENTRYAGGREGATOR => 'AND');
+        $attachments->Limit(FIELD => 'Filename', OPERATOR => '!=', VALUE => '', ENTRYAGGREGATOR => 'AND');
         while (my $attach = $attachments->Next()) {
               next unless ($attach->Filename());
               # most recent at the top

Modified: rt/branches/autrijus-3.1/html/Ticket/Elements/ShowHistory
==============================================================================
--- rt/branches/autrijus-3.1/html/Ticket/Elements/ShowHistory	(original)
+++ rt/branches/autrijus-3.1/html/Ticket/Elements/ShowHistory	Thu Mar  4 10:50:03 2004
@@ -39,7 +39,7 @@
       . "</a>] <b>["
       . loc("Full headers") . "]</b>";
 }
-else {
+elsif ($ShowHeaderModes) {
     $titleright .= "<b>["
       . loc("Brief headers")
       . "]</b> [<A HREF=\""
@@ -49,6 +49,9 @@
       . $Ticket->id . "\">"
       . loc("Full headers") . "</a>]";
 }
+else {
+    $titleright = '';
+}
 </%perl>
 <& /Elements/TitleBoxStart, title => $title, titleright => $titleright, bodyclass=> ''&>
 % }
@@ -83,4 +86,5 @@
 $ShowTitle => 1
 $ShowDisplayModes => 1
 $ShowTitleBarCommands => 1
+$ShowHeaderModes => 1
 </%ARGS>

Modified: rt/branches/autrijus-3.1/html/Ticket/Elements/ShowMessageHeaders
==============================================================================
--- rt/branches/autrijus-3.1/html/Ticket/Elements/ShowMessageHeaders	(original)
+++ rt/branches/autrijus-3.1/html/Ticket/Elements/ShowMessageHeaders	Thu Mar  4 10:50:03 2004
@@ -1,4 +1,4 @@
-%# BEGIN LICENSE BLOCK
+%# BEGIN LICENSE BLOCK;
 %# 
 %# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
 %# 
@@ -21,12 +21,45 @@
 %# 
 %# 
 %# END LICENSE BLOCK
-<%$content |n%>
+% use Data::Dumper;
+<table>
+% foreach my $header (@headers) {
+% next unless ($display_headers{'_all'} || $display_headers{lc($header->{'Tag'})});
+<tr>
+<td align="right" class="message-header-key"><pre><%$header->{'Tag'}%>:</pre></td>
+<td class="message-header-value"><%$header->{'Value'}|n%></td>
+</td>
+</tr>
+% }
+</table>
 <%INIT>
 my $content = $Headers;
 RT::Interface::Web::EscapeUTF8(\$content);
 $m->comp('/Elements/Callback', content => \$content, %ARGS);
+
+
+my @lines = split (/\n/,$content);
+my $in_header = 0;
+my @headers =();
+foreach (@lines) {
+    if (/^(\S+):\s+(.*)$/) {
+        push (@headers, { Tag => $1, Value => $2} ); 
+    } elsif ($headers[-1]) {
+        $headers[-1]->{'Value'} .= $_;
+    } else {
+
+        push (@headers, { Tag => $_, Value => ''} ); 
+    }
+
+}
+
+my %display_headers;
+
+map { $display_headers{lc($_)} = 1 } @$DisplayHeaders;
+
+
 </%INIT>
 <%ARGS>
 $Headers => undef
+$DisplayHeaders => undef
 </%ARGS>

Modified: rt/branches/autrijus-3.1/html/Ticket/Elements/ShowMessageStanza
==============================================================================
--- rt/branches/autrijus-3.1/html/Ticket/Elements/ShowMessageStanza	(original)
+++ rt/branches/autrijus-3.1/html/Ticket/Elements/ShowMessageStanza	Thu Mar  4 10:50:03 2004
@@ -21,8 +21,9 @@
 %# 
 %# 
 %# END LICENSE BLOCK
+% if (ref($Message)) {
+<font color="<%$colors[$Depth]%>">
 <%perl>
-if (ref($Message)) {
 foreach my $stanza (@$Message) {
     if ( ref $stanza eq "ARRAY" ) {
         $m->comp( 'ShowMessageStanza',
@@ -37,9 +38,10 @@
                 $content =~ s/\n/<br>/gi;
 
 </%perl>
-<font color="<%$colors[$Depth]%>"><%$content |n%><br></font>
+<%$content |n%><br>
 %       }
-% }
+% } # end foreach
+</font>
 % } else {
 % my $content = $Message;
 %        RT::Interface::Web::EscapeUTF8(\$content);

Modified: rt/branches/autrijus-3.1/html/Ticket/Elements/ShowTransaction
==============================================================================
--- rt/branches/autrijus-3.1/html/Ticket/Elements/ShowTransaction	(original)
+++ rt/branches/autrijus-3.1/html/Ticket/Elements/ShowTransaction	Thu Mar  4 10:50:03 2004
@@ -36,37 +36,30 @@
 <%PERL>
 
 unless ($Collapsed) {
- $attachments->GotoFirstItem;
- while (my $message=$attachments->Next) {
-     #we don't want to show any empty transactions, unless they have kids
-     next unless ($message->ContentLength || $message->Children->Count);
-
-  my ($headers, $quoted);
-      if ($ShowHeaders && ($ShowHeaders == $Ticket->Id)) {
-	  $headers = $message->Headers;
-      } else {
-	  $headers = $message->NiceHeaders;
-      }
-      chomp $headers;
-      if ($headers) {
-	   # localize the common headers (like 'Subject:'), too.
-	   eval {$headers =~ s/^([^:]+)(?=:)/loc($1)/em; } # we eval here to catch errors when 5.6 panics
-      }
-     # 13456 is a random # of about the biggest size we want to see inline text
-     # It's here to catch anyone who hasn't updated RT_Config.pm since this
-     # constant was moved out there.
-     my $MAX_INLINE_BODY = $RT::MaxInlineBody || 13456;
-     if ($message->ContentType =~ m{^(text/plain|message|text$)}i && 
-				    $message->ContentLength < $MAX_INLINE_BODY ) {
-         eval {
-         require Text::Quoted;
-	     $quoted = Text::Quoted::extract($message->Content); 
-        }; 
-        if ($@) {
-            $quoted = $message->Content;
+    $attachments->GotoFirstItem;
+    while ( my $message = $attachments->Next ) {
+
+        my $quoted;
+        my $headers = $message->Headers;
+        chomp $headers;
+
+        # localize the common headers (like 'Subject:'), too.
+        eval {
+            $headers =~ s/^([^:]+)(?=:)/loc($1)/em;
+          };    # we eval here to catch errors when 5.6 panics
+
+          my $MAX_INLINE_BODY = $RT::MaxInlineBody || 13456;
+        if (    $message->ContentType =~ m{^(text/plain|message|text$)}i
+             && $message->ContentLength < $MAX_INLINE_BODY ) {
+            eval {
+                require Text::Quoted;
+                $quoted = Text::Quoted::extract( $message->Content );
+            };
+            if ($@) {
+                $quoted = $message->Content;
+            }
         }
-     }
-        
+
 </%PERL>
 <TR class="<% $RowNum%2 ? 'oddline' : 'evenline'%>" >                                
       <TD BGCOLOR="<%$bgcolor%>">&nbsp;&nbsp;</TD>
@@ -74,10 +67,12 @@
       <TD COLSPAN=3 VALIGN=TOP>
 <span class="message">
 	<PRE>
-<& ShowMessageHeaders, Headers => $headers, Transaction => $Transaction &>
+<& ShowMessageHeaders, Headers => $headers, Transaction => $Transaction, DisplayHeaders => \@DisplayHeaders &>
 </PRE>
+% if ($ShowBody) {
 % if (!length($quoted) && $message->ContentType =~ m#^text/#) {
-<blockquote><i><&|/l&>Message body not shown because it is too large or is not plain text.</&><br>
+<blockquote><i>
+<&|/l&>Message body not shown because it is too large or is not plain text.</&><br>
 <&|/l&>You can access it with the Download button on the right.</&></i></blockquote>
 % } else {
 <& ShowMessageStanza, Depth => 0, Message => $quoted, Transaction => $Transaction &>
@@ -90,7 +85,7 @@
 <BR>
 % }
 <%PERL>
-my $size = $message->ContentLength;
+my $size = $message->ContentLength or next;
 
 if ($size) {
     if ($size > 1024) {
@@ -102,12 +97,13 @@
 </%PERL>
 <font size=-1><A HREF="<%$AttachPath%>/<%$Transaction->Id%>/<%$message->Id%>/<%$message->Filename | u%>"><&|/l&>Download</&> <% $message->Filename|| loc('(untitled)') %></a> <% $size %></font>
 % }
+% } else {
+<TD>&nbsp;</TD>
+% }
+% }
 </TD>
 </TR>
 % }
-% }
-
-
 
 <%ARGS>
 $Ticket => undef
@@ -117,66 +113,103 @@
 $ShowTitleBarCommands => 1
 $RowNum => 1
 $AttachPath => $RT::WebPath."/Ticket/Attachment"
+$ShowBody => 1
 </%ARGS>
 
 <%INIT>
 
-
-my ($TimeTaken, $TicketString, $bgcolor);
+my ( $TimeTaken, $TicketString, $bgcolor );
 
 my $transdate = $Transaction->CreatedAsString();
 $transdate =~ s/\s/&nbsp;/g;
 
-if ($Transaction->Type =~ /^(Create|Correspond|Comment$)/) {
-	if ($Transaction->IsInbound) {
-		$bgcolor="#336699";
-	}
-	else {
-		$bgcolor="#339999";
-	}
-} elsif (($Transaction->Field =~ /^Owner$/) or 
-	 ($Transaction->Type =~ /^(AddWatcher|DelWatcher)$/)) {
-	$bgcolor="#333399";
-
-} elsif ($Transaction->Type =~ /^(AddLink|DeleteLink)$/) {
-	$bgcolor="#336633";
-} elsif ($Transaction->Type =~ /^(Status|Set|Told)$/) {
-	if ($Transaction->Field =~ /^(Told|Starts|Started|Due)$/) {
-		$bgcolor="#663366";	
-	}
-	else {
-		$bgcolor="#993333";
-	}
+if ( $Transaction->Type =~ /^(Create|Correspond|Comment$)/ ) {
+    if ( $Transaction->IsInbound ) {
+        $bgcolor = "#336699";
+    }
+    else {
+        $bgcolor = "#339999";
+    }
+}
+elsif (    ( $Transaction->Field =~ /^Owner$/ )
+        or ( $Transaction->Type =~ /^(AddWatcher|DelWatcher)$/ ) ) {
+    $bgcolor = "#333399";
+
+}
+elsif ( $Transaction->Type =~ /^(AddLink|DeleteLink)$/ ) {
+    $bgcolor = "#336633";
+}
+elsif ( $Transaction->Type =~ /^(Status|Set|Told)$/ ) {
+    if ( $Transaction->Field =~ /^(Told|Starts|Started|Due)$/ ) {
+        $bgcolor = "#663366";
+    }
+    else {
+        $bgcolor = "#993333";
+    }
 }
 else {
-	$bgcolor="#cccccc";
+    $bgcolor = "#cccccc";
 }
 
-if ($Ticket->Id != $Transaction->Ticket) {
-	$TicketString = "Ticket ".$Transaction->Ticket .": ";
+if ( $Ticket->Id != $Transaction->Ticket ) {
+    $TicketString = "Ticket " . $Transaction->Ticket . ": ";
 }
 
-if ($Transaction->TimeTaken > 0) {
-	$TimeTaken = $Transaction->TimeTaken." min"
+if ( $Transaction->TimeTaken > 0 ) {
+    $TimeTaken = $Transaction->TimeTaken . " min";
 }
 my $attachments = $Transaction->Attachments;
+$attachments->Columns( qw( Id Filename ContentType Headers Subject Parent ContentEncoding ContentType TransactionId)
+);
 
-my $titlebar_commands='&nbsp;';
+my $titlebar_commands = '&nbsp;';
 
-# If the transaction has anything attached to it at all
-if ($Transaction->Attachments->First && $ShowTitleBarCommands) {
-	if ($Transaction->TicketObj->CurrentUserHasRight('ReplyToTicket')) {
-		$titlebar_commands .= 
-	  	  "[<a href=\"Update.html?id=".
-		  $Transaction->Ticket . "&QuoteTransaction=".$Transaction->Id.
-		  "&Action=Respond\">". loc('Reply') ."</a>]&nbsp;";
-	}
-	if ($Transaction->TicketObj->CurrentUserHasRight('CommentOnTicket')) {
-	     $titlebar_commands .= 
-	     "[<a href=\"Update.html?id=".$Transaction->Ticket. 
-	     "&QuoteTransaction=".$Transaction->Id.
-	     "&Action=Comment\">". loc('Comment') ."</a>]";
-	}
+my @DisplayHeaders=qw ( _all);
+
+if ( $Transaction->Type =~ /EmailRecord$/ ) {
+    @DisplayHeaders = qw(To Cc Bcc);
+
+    $titlebar_commands .=
+        "[<a target=\"_blank\" href=\"ShowEmailRecord.html?id="
+      . $Transaction->Ticket
+      . "&Transaction="
+      . $Transaction->Id
+      . "&Attachment="
+      . (    $Transaction->Attachments->First
+          && $Transaction->Attachments->First->Id )
+
+      . '">' . loc('Show') . "</a>]&nbsp;";
+    $ShowBody = 0;
 }
 
+
+# If the transaction has anything attached to it at all
+else {
+
+    unless ( $ShowHeaders && ( $ShowHeaders == $Ticket->Id ) ) {
+        @DisplayHeaders = qw(To From RT-Send-Cc Cc Bcc Date Subject);
+    }
+
+    if ( $Transaction->Attachments->First && $ShowTitleBarCommands ) {
+        if ( $Transaction->TicketObj->CurrentUserHasRight('ReplyToTicket') ) {
+            $titlebar_commands .=
+                "[<a href=\"Update.html?id="
+              . $Transaction->Ticket
+              . "&QuoteTransaction="
+              . $Transaction->Id
+              . "&Action=Respond\">"
+              . loc('Reply')
+              . "</a>]&nbsp;";
+        }
+        if ( $Transaction->TicketObj->CurrentUserHasRight('CommentOnTicket') ) {
+            $titlebar_commands .=
+                "[<a href=\"Update.html?id="
+              . $Transaction->Ticket
+              . "&QuoteTransaction="
+              . $Transaction->Id
+              . "&Action=Comment\">"
+              . loc('Comment') . "</a>]";
+        }
+    }
+}
 </%INIT>

Modified: rt/branches/autrijus-3.1/html/autohandler
==============================================================================
--- rt/branches/autrijus-3.1/html/autohandler	(original)
+++ rt/branches/autrijus-3.1/html/autohandler	Thu Mar  4 10:50:03 2004
@@ -28,6 +28,12 @@
 
 
 local *session unless $m->is_subrequest; # avoid reentrancy, as suggested by masonbook
+
+# Disable AutoFlush using an attribute
+if ($m->request_comp->attr_exists('AutoFlush')) {
+    $m->autoflush($m->request_comp->attr('AutoFlush'));
+}
+
 %ARGS = map {
     # if they've passed multiple values, they'll be an array. if they've 
     # passed just one, a scalar whatever they are, mark them as utf8

Modified: rt/branches/autrijus-3.1/lib/RT/Action/SendEmail.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/Action/SendEmail.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/Action/SendEmail.pm	Thu Mar  4 10:50:03 2004
@@ -339,7 +339,15 @@
 
     # XXX: TODO -> Record attachments as references to things in the attachments table, maybe.
 
-    my ($id, $msg) = $transaction->Create( Ticket => $self->TicketObj->Id, Type => 'EmailRecord', Data => $MIMEObj->head->get('Message-Id'), MIMEObj => $MIMEObj, ActivateScrips => 0);
+    my $type;
+    if ($self->TransactionObj->Type eq 'Comment') {
+        $type = 'CommentEmailRecord';
+    } else {
+        $type = 'EmailRecord';
+    }
+
+
+    my ($id, $msg) = $transaction->Create( Ticket => $self->TicketObj->Id, Type => $type, Data => $MIMEObj->head->get('Message-Id'), MIMEObj => $MIMEObj, ActivateScrips => 0);
 
 
 }

Modified: rt/branches/autrijus-3.1/lib/RT/Attachment_Overlay.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/Attachment_Overlay.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/Attachment_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -440,7 +440,7 @@
     my $hdrs = "";
     my @hdrs = split(/\n/,$self->Headers);
     while (my $str = shift @hdrs) {
-	    next unless $str =~ /^(To|From|RT-Send-Cc|Cc|Date|Subject): /i;
+	    next unless $str =~ /^(To|From|RT-Send-Cc|Cc|Bcc:Date|Subject): /i;
 	    $hdrs .= $str . "\n";
 	    $hdrs .= shift( @hdrs ) . "\n" while ($hdrs[0] =~ /^[ \t]+/);
     }
@@ -581,5 +581,14 @@
 }
 
 # }}}
+
+# Transactions don't change. by adding this cache congif directiove, we don't lose pathalogically on long tickets.
+sub _CacheConfig {
+    {
+        'cache_p'         => 1,
+          'fast_update_p' => 1,
+          'cache_for_sec' => 180,
+    }
+}
 
 1;

Modified: rt/branches/autrijus-3.1/lib/RT/CustomField.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/CustomField.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/CustomField.pm	Thu Mar  4 10:50:03 2004
@@ -70,8 +70,12 @@
   varchar(200) 'Type'.
   int(11) 'MaxValues'.
   varchar(255) 'Pattern'.
+  smallint(6) 'Repeated'.
   varchar(255) 'Description'.
   int(11) 'SortOrder'.
+  varchar(255) 'ObjectType'.
+  varchar(255) 'IntermediateType'.
+  varchar(255) 'ParentType'.
   smallint(6) 'Disabled'.
 
 =cut
@@ -86,8 +90,12 @@
                 Type => '',
                 MaxValues => '',
                 Pattern => '',
+                Repeated => '0',
                 Description => '',
                 SortOrder => '0',
+                ObjectType => '',
+                IntermediateType => '',
+                ParentType => '',
                 Disabled => '0',
 
 		  @_);
@@ -96,8 +104,12 @@
                          Type => $args{'Type'},
                          MaxValues => $args{'MaxValues'},
                          Pattern => $args{'Pattern'},
+                         Repeated => $args{'Repeated'},
                          Description => $args{'Description'},
                          SortOrder => $args{'SortOrder'},
+                         ObjectType => $args{'ObjectType'},
+                         IntermediateType => $args{'IntermediateType'},
+                         ParentType => $args{'ParentType'},
                          Disabled => $args{'Disabled'},
 );
 
@@ -186,6 +198,24 @@
 =cut
 
 
+=head2 Repeated
+
+Returns the current value of Repeated. 
+(In the database, Repeated is stored as smallint(6).)
+
+
+
+=head2 SetRepeated VALUE
+
+
+Set Repeated to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Repeated will be stored as a smallint(6).)
+
+
+=cut
+
+
 =head2 Description
 
 Returns the current value of Description. 
@@ -222,6 +252,60 @@
 =cut
 
 
+=head2 ObjectType
+
+Returns the current value of ObjectType. 
+(In the database, ObjectType is stored as varchar(255).)
+
+
+
+=head2 SetObjectType VALUE
+
+
+Set ObjectType to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ObjectType will be stored as a varchar(255).)
+
+
+=cut
+
+
+=head2 IntermediateType
+
+Returns the current value of IntermediateType. 
+(In the database, IntermediateType is stored as varchar(255).)
+
+
+
+=head2 SetIntermediateType VALUE
+
+
+Set IntermediateType to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, IntermediateType will be stored as a varchar(255).)
+
+
+=cut
+
+
+=head2 ParentType
+
+Returns the current value of ParentType. 
+(In the database, ParentType is stored as varchar(255).)
+
+
+
+=head2 SetParentType VALUE
+
+
+Set ParentType to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ParentType will be stored as a varchar(255).)
+
+
+=cut
+
+
 =head2 Creator
 
 Returns the current value of Creator. 
@@ -290,10 +374,18 @@
 		{read => 1, write => 1, type => 'int(11)', default => ''},
         Pattern => 
 		{read => 1, write => 1, type => 'varchar(255)', default => ''},
+        Repeated => 
+		{read => 1, write => 1, type => 'smallint(6)', default => '0'},
         Description => 
 		{read => 1, write => 1, type => 'varchar(255)', default => ''},
         SortOrder => 
 		{read => 1, write => 1, type => 'int(11)', default => '0'},
+        ObjectType => 
+		{read => 1, write => 1, type => 'varchar(255)', default => ''},
+        IntermediateType => 
+		{read => 1, write => 1, type => 'varchar(255)', default => ''},
+        ParentType => 
+		{read => 1, write => 1, type => 'varchar(255)', default => ''},
         Creator => 
 		{read => 1, auto => 1, type => 'int(11)', default => '0'},
         Created => 

Modified: rt/branches/autrijus-3.1/lib/RT/CustomField_Overlay.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/CustomField_Overlay.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/CustomField_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -24,24 +24,39 @@
 use strict;
 no warnings qw(redefine);
 
-use vars qw(@TYPES %TYPES);
+use vars qw(@TYPES %TYPES $RIGHTS);
 
 use RT::CustomFieldValues;
 use RT::ObjectCustomFieldValues;
 
 # Enumerate all valid types for this custom field
 @TYPES = (
-    'SelectSingle',	# loc
-    'SelectMultiple',	# loc
-    'FreeformSingle',	# loc
-    'FreeformMultiple', # loc
+    'Freeform',	# loc
+    'Text',     # loc
+    'Select',	# loc
+    'Image',    # loc
+    'Binary',   # loc
 );
 
 # Populate a hash of types of easier validation
 for (@TYPES) { $TYPES{$_} = 1};
 
+$RIGHTS = {
+    SeeCustomField            => 'Can this principal see this custom field',       # loc_pair
+    AdminCustomField          => 'Create, delete and modify custom fields',        # loc_pair
+};
 
+# Tell RT::ACE that this sort of object can get acls granted
+$RT::ACE::OBJECT_TYPES{'RT::CustomField'} = 1;
 
+foreach my $right ( keys %{$RIGHTS} ) {
+    $RT::ACE::LOWERCASERIGHTNAMES{ lc $right } = $right;
+}
+
+sub AvailableRights {
+    my $self = shift;
+    return($RIGHTS);
+}
 
 =head1 NAME
 
@@ -77,14 +92,25 @@
     my %args = ( 
                 Name => '',
                 Type => '',
-		MaxValues => 0,
+		MaxValues => '0',
 		Pattern  => '',
                 Description => '',
                 SortOrder => '0',
                 Disabled => '0',
+		ObjectType  => '',
+		IntermediateType  => '',
+		ParentType  => '',
+		Repeated  => '0',
 
 		  @_);
 
+    if ($args{TypeComposite}) {
+	@args{'Type', 'MaxValues'} = split(/-/, $args{TypeComposite}, 2);
+    }
+    if ($args{ObjectTypeComposite}) {
+	@args{'ObjectType', 'IntermediateType', 'ParentType'}
+	    = split(/-/, $args{ObjectTypeComposite}, 3);
+    }
     
     if ( !exists $args{'Queue'}) {
 	# do nothing -- things below are strictly backward compat
@@ -112,6 +138,10 @@
                          Description => $args{'Description'},
                          SortOrder => $args{'SortOrder'},
                          Disabled => $args{'Disabled'},
+			 ObjectType => $args{'ObjectType'},
+			 IntermediateType => $args{'IntermediateType'},
+			 ParentType => $args{'ParentType'},
+			 Repeated => $args{'Repeated'},
 );
 
     return $rv unless exists $args{'Queue'};
@@ -301,6 +331,11 @@
     return ($cf_values);
 }
 
+sub ValuesObj {
+    my $self = shift;
+    return $self->Values(@_);
+}
+
 # }}}
 
 # }}}
@@ -433,35 +468,61 @@
 # }}}
 
 
-=head2 FriendlyType [TYPE]
+=head2 FriendlyType [TYPE, MAX_VALUES]
 
 Returns a localized human-readable version of the custom field type.
 If a custom field type is specified as the parameter, the friendly type for that type will be returned
 
 =cut
 
+my %FriendlyTypes = (
+    Select => [
+        'Select multiple values',	# loc
+        'Select one value',		# loc
+        'Select up to [_1] values',	# loc
+    ],
+    Freeform => [
+        'Enter multiple values',	# loc
+        'Enter one value',		# loc
+        'Enter up to [_1] values',	# loc
+    ],
+    Text => [
+        'Enter multiple text areas',	# loc
+        'Enter one text area',		# loc
+        'Enter up to [_1] text areas',	# loc
+    ],
+    Image => [
+        'Upload multiple images',	# loc
+        'Upload one image',		# loc
+        'Upload up to [_1] images',	# loc
+    ],
+    Binary => [
+        'Upload multiple files',	# loc
+        'Upload one files',		# loc
+        'Upload up to [_1] files',	# loc
+    ],
+);
+
 sub FriendlyType {
     my $self = shift;
 
-    my $type = shift || $self->Type;
+    my $type = @_ ? shift : $self->Type;
+    my $max  = @_ ? shift : $self->MaxValues;
 
-    if ( $type eq 'SelectSingle' ) {
-        return ( $self->loc('Select one value') );
-    }
-    elsif ( $type eq 'SelectMultiple' ) {
-        return ( $self->loc('Select multiple values') );
-    }
-    elsif ( $type eq 'FreeformSingle' ) {
-        return ( $self->loc('Enter one value') );
-    }
-    elsif ( $type eq 'FreeformMultiple' ) {
-        return ( $self->loc('Enter multiple values') );
+    if (my $friendly_type = $FriendlyTypes{$type}[$max>2 ? 2 : $max]) {
+	return ( $self->loc( $friendly_type, $max ) );
     }
     else {
-        return ( $self->loc( $self->Type ) );
+        return ( $self->loc( $type ) );
     }
 }
 
+sub FriendlyTypeComposite {
+    my $self = shift;
+    my $composite = shift || $self->TypeComposite;
+    return $self->FriendlyType(split(/-/, $composite, 2));
+}
+
 
 =head2 ValidateType TYPE
 
@@ -594,6 +655,121 @@
 
 sub SetQueue {
     return 0;
+}
+
+sub SetTypeComposite {
+    my $self = shift;
+    my $composite = shift;
+    my ($type, $max_values) = split(/-/, $composite, 2);
+    $self->SetType($type);
+    $self->SetMaxValues($max_values);
+}
+
+sub SetObjectTypeComposite {
+    my $self = shift;
+    my $composite = shift;
+    my ($o_type, $i_type, $p_type) = split(/-/, $composite, 3);
+    $self->SetObjectType("$o_type");
+    $self->SetIntermediateType("$i_type");
+    $self->SetParentType("$p_type");
+}
+
+sub TypeComposite {
+    my $self = shift;
+    join('-', $self->Type, $self->MaxValues);
+}
+
+sub ObjectTypeComposite {
+    my $self = shift;
+    join('-', $self->ObjectType, $self->IntermediateType, $self->ParentType);
+}
+
+sub TypeComposites {
+    my $self = shift;
+    return map { ("$_-1", "$_-0") } $self->Types;
+}
+
+sub ObjectTypeComposites {
+    my $self = shift;
+    qw(
+	RT::Ticket--RT::Queue
+	RT::User--
+	RT::Group--
+    );
+}
+
+my @FriendlyObjectTypes = (
+    "[_1] objects",		    # loc
+    "[_2]'s [_1] objects",	    # loc
+    "[_3]'s [_2]'s [_1] objects",   # loc
+);
+
+sub FriendlyObjectType {
+    my $self = shift;
+    my $o_type = @_ ? shift : $self->ObjectType;
+    my $i_type = @_ ? shift : $self->IntermediateType;
+    my $p_type = @_ ? shift : $self->ParentType;
+    my @types = map { s/^RT::// ? $self->loc($_) : $_ }
+		grep {defined and length}
+		$o_type, $i_type, $p_type or return;
+    return ( $self->loc( $FriendlyObjectTypes[$#types], @types ) );
+}
+
+sub FriendlyObjectTypeComposite {
+    my $self = shift;
+    my $composite = shift || $self->ObjectTypeComposite;
+    return $self->FriendlyObjectType(split(/-/, $composite, 3));
+}
+
+sub AddToParent {
+    my $self  = shift;
+    my $object = shift;
+    my $composite = shift || ref($object)."--";
+    my $id = $object->Id || 0;
+
+    unless ($self->ObjectTypeComposite eq $composite) {
+	return ( 0, $self->loc('Object type mismatch') );
+    }
+
+    unless ( $object->CurrentUserHasRight('AdminCustomFields') ) {
+        return ( 0, $self->loc('Permission Denied') );
+    }
+
+    my $ObjectCF = RT::ObjectCustomField->new( $self->CurrentUser );
+
+    $ObjectCF->LoadByCols( ParentId => $id, CustomField => $self->Id );
+    if ( $ObjectCF->Id ) {
+        return ( 0, $self->loc("That is already the current value") );
+    }
+    my ( $id, $msg ) =
+      $ObjectCF->Create( ParentId => $id, CustomField => $self->Id );
+
+    return ( $id, $msg );
+}
+
+sub RemoveFromParent {
+    my $self = shift;
+    my $object = shift;
+    my $composite = shift || ref($object)."--";
+    my $id = $object->Id || 0;
+
+    unless ($self->ObjectTypeComposite eq $composite) {
+	return ( 0, $self->loc('Object type mismatch') );
+    }
+
+    unless ( $object->CurrentUserHasRight('AdminCustomFields') ) {
+        return ( 0, $self->loc('Permission Denied') );
+    }
+
+    my $ObjectCF = RT::ObjectCustomField->new( $self->CurrentUser );
+
+    $ObjectCF->LoadByCols( ParentId => $id, CustomField => $self->Id );
+    unless ( $ObjectCF->Id ) {
+        return ( 0, $self->loc("This custom field does not apply to that object") );
+    }
+    my ( $id, $msg ) = $ObjectCF->Delete;
+
+    return ( $id, $msg );
 }
 
 1;

Modified: rt/branches/autrijus-3.1/lib/RT/CustomFields_Overlay.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/CustomFields_Overlay.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/CustomFields_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -148,6 +148,87 @@
 }
 
 # }}}
+
+# {{{ sub Next 
+
+=head2 Next
+
+Returns the next custom field that this user can see.
+
+=cut
+  
+sub Next {
+    my $self = shift;
+    
+    
+    my $CF = $self->SUPER::Next();
+    if ((defined($CF)) and (ref($CF))) {
+
+	if ($CF->CurrentUserHasRight('SeeCustomField')) {
+	    return($CF);
+	}
+	
+	#If the user doesn't have the right to show this queue
+	else {	
+	    return($self->Next());
+	}
+    }
+    #if there never was any queue
+    else {
+	return(undef);
+    }	
+    
+}
+# }}}
+
+sub LimitToParentId  {
+    my $self = shift;
+    my $id = shift || 0;
+ 
+    $self->Limit( FIELD => 'ParentId', VALUE => "$id" );
+}
+
+sub LimitToObjectType  {
+    my $self = shift;
+    my $o_type = shift;
+ 
+    $self->Limit( FIELD => 'ObjectType', VALUE => "$o_type" );
+}
+
+sub LimitToComposite  {
+    my $self = shift;
+    my $composite = shift;
+    my ($o_type, $i_type, $p_type) = split(/-/, $composite, 3);
+ 
+    $self->Limit( FIELD => 'ObjectType', VALUE => "$o_type" );
+    $self->Limit( FIELD => 'IntermediateType', VALUE => "$i_type" );
+    $self->Limit( FIELD => 'ParentType', VALUE => "$p_type" );
+}
+
+sub LimitToGlobalOrParentId {
+    my $self = shift;
+    my $id = shift || 0;
+
+    my $object_cfs = $self->NewAlias('ObjectCustomFields');
+    $self->Join( ALIAS1 => 'main',
+                FIELD1 => 'id',
+                ALIAS2 => $object_cfs,
+                FIELD2 => 'CustomField' );
+    $self->Limit( ALIAS           => $object_cfs,
+                 FIELD           => 'ParentId',
+                 OPERATOR        => '=',
+                 VALUE           => $id,
+                 ENTRYAGGREGATOR => 'OR' );
+    $self->Limit( ALIAS           => $object_cfs,
+                 FIELD           => 'ParentId',
+                 OPERATOR        => '=',
+                 VALUE           => 0,
+                 ENTRYAGGREGATOR => 'OR' ) if $id;
+    
+    # This doesn't work on postgres. 
+    #$self->OrderBy( ALIAS => $class_cfs , FIELD => "SortOrder", ORDER => 'ASC');
+
+}
   
 1;
 

Modified: rt/branches/autrijus-3.1/lib/RT/Group_Overlay.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/Group_Overlay.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/Group_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -1155,6 +1155,13 @@
 # {{{ sub _Set
 sub _Set {
     my $self = shift;
+    my %args = (
+        Field => undef,
+        Value => undef,
+	TransactionType   => 'Set',
+	RecordTransaction => 1,
+        @_
+    );
 
 	if ($self->Domain eq 'Personal') {
    		if ($self->CurrentUser->PrincipalId == $self->Instance) {
@@ -1172,7 +1179,22 @@
         	return ( 0, $self->loc('Permission Denied') );
     	}
 	}
-    return ( $self->SUPER::_Set(@_) );
+
+    my ($ret, $msg) = ( $self->SUPER::_Set(@_) );
+
+    if ( $args{'RecordTransaction'} == 1 ) {
+
+        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+                                               Type => $args{'TransactionType'},
+                                               Field     => $args{'Field'},
+                                               NewValue  => $args{'Value'},
+                                               OldValue  => $self->SUPER::_Value("$args{'Field'}"),
+        );
+        return ( $Trans, scalar $TransObj->Description );
+    }
+    else {
+        return ( $ret, $msg );
+    }
 }
 
 # }}}

Modified: rt/branches/autrijus-3.1/lib/RT/Handle.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/Handle.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/Handle.pm	Thu Mar  4 10:50:03 2004
@@ -60,9 +60,12 @@
 sub Connect {
 my $self=shift;
 
-# Unless the database port is a positive integer, we really don't want to pass it.
 
-$self->SUPER::Connect(
+    if ($RT::DatabaseType eq 'Oracle') {
+        $ENV{'NLS_LANG'} = ".UTF8";
+    }
+
+    $self->SUPER::Connect(
 			 User => $RT::DatabaseUser,
 			 Password => $RT::DatabasePassword,
 			);
@@ -79,8 +82,10 @@
 
 sub BuildDSN {
     my $self = shift;
+# Unless the database port is a positive integer, we really don't want to pass it.
 $RT::DatabasePort = undef unless (defined $RT::DatabasePort && $RT::DatabasePort =~ /^(\d+)$/);
 $RT::DatabaseHost = undef unless (defined $RT::DatabaseHost && $RT::DatabaseHost ne '');
+
 
     $self->SUPER::BuildDSN(Host => $RT::DatabaseHost, 
 			 Database => $RT::DatabaseName, 

Modified: rt/branches/autrijus-3.1/lib/RT/ObjectCustomField.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/ObjectCustomField.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/ObjectCustomField.pm	Thu Mar  4 10:50:03 2004
@@ -68,10 +68,9 @@
 Create takes a hash of values and creates a row in the database:
 
   int(11) 'CustomField'.
-  varchar(255) 'ObjectType'.
-  varchar(255) 'IntermediateType'.
-  varchar(255) 'ParentType'.
   int(11) 'ParentId'.
+  int(11) 'SortOrder'.
+  int(11) 'SortOrder'.
 
 =cut
 
@@ -82,18 +81,16 @@
     my $self = shift;
     my %args = ( 
                 CustomField => '0',
-                ObjectType => '',
-                IntermediateType => '',
-                ParentType => '',
                 ParentId => '0',
+                SortOrder => '0',
+                SortOrder => '0',
 
 		  @_);
     $self->SUPER::Create(
                          CustomField => $args{'CustomField'},
-                         ObjectType => $args{'ObjectType'},
-                         IntermediateType => $args{'IntermediateType'},
-                         ParentType => $args{'ParentType'},
                          ParentId => $args{'ParentId'},
+                         SortOrder => $args{'SortOrder'},
+                         SortOrder => $args{'SortOrder'},
 );
 
 }
@@ -141,73 +138,37 @@
 	return($CustomField);
 }
 
-=head2 ObjectType
-
-Returns the current value of ObjectType. 
-(In the database, ObjectType is stored as varchar(255).)
-
-
-
-=head2 SetObjectType VALUE
-
-
-Set ObjectType to VALUE. 
-Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, ObjectType will be stored as a varchar(255).)
-
-
-=cut
-
-
-=head2 IntermediateType
-
-Returns the current value of IntermediateType. 
-(In the database, IntermediateType is stored as varchar(255).)
-
-
-
-=head2 SetIntermediateType VALUE
-
-
-Set IntermediateType to VALUE. 
-Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, IntermediateType will be stored as a varchar(255).)
-
-
-=cut
-
-
-=head2 ParentType
+=head2 ParentId
 
-Returns the current value of ParentType. 
-(In the database, ParentType is stored as varchar(255).)
+Returns the current value of ParentId. 
+(In the database, ParentId is stored as int(11).)
 
 
 
-=head2 SetParentType VALUE
+=head2 SetParentId VALUE
 
 
-Set ParentType to VALUE. 
+Set ParentId to VALUE. 
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, ParentType will be stored as a varchar(255).)
+(In the database, ParentId will be stored as a int(11).)
 
 
 =cut
 
 
-=head2 ParentId
+=head2 SortOrder
 
-Returns the current value of ParentId. 
-(In the database, ParentId is stored as int(11).)
+Returns the current value of SortOrder. 
+(In the database, SortOrder is stored as int(11).)
 
 
 
-=head2 SetParentId VALUE
+=head2 SetSortOrder VALUE
 
 
-Set ParentId to VALUE. 
+Set SortOrder to VALUE. 
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, ParentId will be stored as a int(11).)
+(In the database, SortOrder will be stored as a int(11).)
 
 
 =cut
@@ -257,13 +218,9 @@
 		{read => 1, type => 'int(11)', default => ''},
         CustomField => 
 		{read => 1, write => 1, type => 'int(11)', default => '0'},
-        ObjectType => 
-		{read => 1, write => 1, type => 'varchar(255)', default => ''},
-        IntermediateType => 
-		{read => 1, write => 1, type => 'varchar(255)', default => ''},
-        ParentType => 
-		{read => 1, write => 1, type => 'varchar(255)', default => ''},
         ParentId => 
+		{read => 1, write => 1, type => 'int(11)', default => '0'},
+        SortOrder => 
 		{read => 1, write => 1, type => 'int(11)', default => '0'},
         Creator => 
 		{read => 1, auto => 1, type => 'int(11)', default => '0'},

Added: rt/branches/autrijus-3.1/lib/RT/ObjectCustomField_Overlay.pm
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/lib/RT/ObjectCustomField_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,28 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+# 
+# This work 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+no warnings qw(redefine);
+
+1;

Modified: rt/branches/autrijus-3.1/lib/RT/ObjectCustomFields.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/ObjectCustomFields.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/ObjectCustomFields.pm	Thu Mar  4 10:50:03 2004
@@ -61,6 +61,12 @@
     $self->{'primary_key'} = 'id';
 
 
+
+  # By default, order by name
+  $self->OrderBy( ALIAS => 'main',
+                  FIELD => 'SortOrder',
+                  ORDER => 'ASC');
+
     return ( $self->SUPER::_Init(@_) );
 }
 

Added: rt/branches/autrijus-3.1/lib/RT/ObjectCustomFields_Overlay.pm
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/lib/RT/ObjectCustomFields_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,58 @@
+# BEGIN LICENSE BLOCK
+# 
+# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+# 
+# (Except where explictly superceded by other copyright notices)
+# 
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+# 
+# This work 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.
+# 
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# 
+# 
+# END LICENSE BLOCK
+
+use strict;
+no warnings qw(redefine);
+
+sub LimitToParentAndComposite {
+    my $self = shift;
+    my %args = @_;
+    my $composite = $args{Composite} or die "Must specify Composite";
+    my $ParentObj = $args{Parent};
+    my $ParentType = $args{ParentType} || ref($ParentObj) or die "Must specify ParentType";
+    my $ParentId = $args{ParentId} || ($ParentObj ? $ParentObj->Id || 0 : 0);
+    $self->Limit( FIELD => 'ParentId', VALUE => $ParentId );
+
+    # $self->Limit( FIELD => 'ParentId', VALUE => '0' ) if $ParentId;
+    # XXX - Join CF here and limit its composites 
+}
+
+sub HasEntryForCustomField {
+    my $self = shift;
+    my $id = shift;
+
+    my @items = grep {$_->CustomField == $id } @{$self->ItemsArrayRef};
+
+    if ($#items > 1) {
+	die "$self HasEntry had a list with more than one of $id in it. this can never happen";
+    }
+    if ($#items == -1 ) {
+	return undef;
+    }
+    else {
+	return ($items[0]);
+    }  
+}
+
+1;

Modified: rt/branches/autrijus-3.1/lib/RT/Queue_Overlay.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/Queue_Overlay.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/Queue_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -68,7 +68,7 @@
     ShowACL             => 'Display Access Control List',             # loc_pair
     ModifyACL           => 'Modify Access Control List',              # loc_pair
     ModifyQueueWatchers => 'Modify the queue watchers',               # loc_pair
-    AdminCustomFields   => 'Create, delete and modify custom fields', # loc_pair
+    AdminCustomFields   => 'Assign and remove custom fields',         # loc_pair
     ModifyTemplate      => 'Modify Scrip templates for this queue',   # loc_pair
     ShowTemplate        => 'Display Scrip templates for this queue',  # loc_pair
 

Modified: rt/branches/autrijus-3.1/lib/RT/Record.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/Record.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/Record.pm	Thu Mar  4 10:50:03 2004
@@ -585,6 +585,103 @@
 
 }
 
+# {{{ sub _NewTransaction
+
+=head2 _NewTransaction  PARAMHASH
+
+Private function to create a new RT::Transaction object for this ticket update
+
+=cut
+
+sub _NewTransaction {
+    my $self = shift;
+    my %args = (
+        TimeTaken => undef,
+        Type      => undef,
+        OldValue  => undef,
+        NewValue  => undef,
+        Data      => undef,
+        Field     => undef,
+        MIMEObj   => undef,
+        ActivateScrips => 1,
+        CommitScrips => 1,
+        @_
+    );
+
+    require RT::Transaction;
+    my $trans = new RT::Transaction( $self->CurrentUser );
+    my ( $transaction, $msg ) = $trans->Create(
+	ObjectId  => $self->Id,
+	ObjectType => ref($self),
+        TimeTaken => $args{'TimeTaken'},
+        Type      => $args{'Type'},
+        Data      => $args{'Data'},
+        Field     => $args{'Field'},
+        NewValue  => $args{'NewValue'},
+        OldValue  => $args{'OldValue'},
+        MIMEObj   => $args{'MIMEObj'},
+        ActivateScrips => $args{'ActivateScrips'},
+        CommitScrips => $args{'CommitScrips'},
+    );
+
+    # Rationalize the object since we may have done things to it during the caching.
+    $self->Load($self->Id);
+
+    $RT::Logger->warning($msg) unless $transaction;
+
+    $self->_SetLastUpdated;
+
+    if ( defined $args{'TimeTaken'} ) {
+        $self->_UpdateTimeTaken( $args{'TimeTaken'} );
+    }
+    if ( $RT::UseTransactionBatch and $transaction ) {
+	    push @{$self->{_TransactionBatch}}, $trans;
+    }
+    return ( $transaction, $msg, $trans );
+}
+
+# }}}
+
+# {{{ sub Transactions 
+
+=head2 Transactions
+
+  Returns an RT::Transactions object of all transactions on this ticket
+
+=cut
+
+sub Transactions {
+    my $self = shift;
+
+    use RT::Transactions;
+    my $transactions = RT::Transactions->new( $self->CurrentUser );
+
+    #If the user has no rights, return an empty object
+    $transactions->Limit(
+	FIELD => 'ObjectId',
+	VALUE => $self->id,
+    );
+    $transactions->Limit(
+	FIELD    => 'ObjectType',
+	VALUE    => ref($self),
+    );
+
+    return ($transactions);
+}
+
+# }}}
+
+sub CustomFields {
+    my $self = shift;
+    my $cfs = RT::CustomFields->new( $self->CurrentUser );
+    $cfs->UnLimit;
+    $cfs->LimitToComposite(ref($self).'--');
+    $cfs->LimitToGlobalOrParentId($self->Id);
+    return $cfs;
+}
+
+
+
 
 eval "require RT::Record_Vendor";
 die $@ if ($@ && $@ !~ qr{^Can't locate RT/Record_Vendor.pm});

Modified: rt/branches/autrijus-3.1/lib/RT/StyleGuide.pod
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/StyleGuide.pod	(original)
+++ rt/branches/autrijus-3.1/lib/RT/StyleGuide.pod	Thu Mar  4 10:50:03 2004
@@ -804,11 +804,9 @@
 
 This is for new programs, modules, specific APIs, or anything else.
 
-Contact for core team is the slashcode-development mailing list.
-
 =over 4
 
-=item Present idea to core team
+=item Present idea to rt-devel
 
 We may know of a better way to approach the problem, or know of an
 existing way to deal with it, or know someone else is working on it. 
@@ -816,9 +814,9 @@
 and use of the code should be provided.
 
 
-=item Present complete specs to core team
+=item Present complete specs to rt-devel
 
-The complete proposed API to the core team should be submitted for
+The complete proposed API  should be submitted for
 approval and discussion.  For web and command-line programs, present the
 functionality and interface (op codes, command-lin switches, etc.).
 
@@ -827,13 +825,8 @@
 but fill it in as much as you can.
 
 
-=item Announce any changes to interface
-
-If the way it works or how it is called is going to change, notify the core
-team.
 
-
-=item Prepare for core review
+=item Prepare for code review
 
 When you are done, the code will undergo a code review by a member of
 the core team, or someone picked by the core team.  This is not to
@@ -842,9 +835,6 @@
 break other code, that it follows the documentation and existing
 proposal.  It is to check for possible optimizations or better ways of
 doing it.
-
-For members of the core team, one or more other members of the team will
-perform the review.
 
 Note that all code is expected to follow the coding principles and style
 guide contained in this document.

Modified: rt/branches/autrijus-3.1/lib/RT/Ticket_Overlay.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/Ticket_Overlay.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/Ticket_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -3849,110 +3849,6 @@
 
 # }}}
 
-# {{{ sub Transactions 
-
-=head2 Transactions
-
-  Returns an RT::Transactions object of all transactions on this ticket
-
-=cut
-
-sub Transactions {
-    my $self = shift;
-
-    use RT::Transactions;
-    my $transactions = RT::Transactions->new( $self->CurrentUser );
-
-    #If the user has no rights, return an empty object
-    if ( $self->CurrentUserHasRight('ShowTicket') ) {
-        my $tickets = $transactions->NewAlias('Tickets');
-        $transactions->Join(
-            ALIAS1 => 'main',
-            FIELD1 => 'ObjectId',
-            ALIAS2 => $tickets,
-            FIELD2 => 'id'
-        );
-        $transactions->Limit(
-            ALIAS => $tickets,
-            FIELD => 'EffectiveId',
-            VALUE => $self->id()
-        );
-	$transactions->Limit(
-	    FIELD    => 'ObjectType',
-	    VALUE    => ref($self),
-	);
-
-        # if the user may not see comments do not return them
-        unless ( $self->CurrentUserHasRight('ShowTicketComments') ) {
-            $transactions->Limit(
-                FIELD    => 'Type',
-                OPERATOR => '!=',
-                VALUE    => "Comment"
-            );
-        }
-    }
-
-    return ($transactions);
-}
-
-# }}}
-
-# {{{ sub _NewTransaction
-
-=head2 _NewTransaction  PARAMHASH
-
-Private function to create a new RT::Transaction object for this ticket update
-
-=cut
-
-sub _NewTransaction {
-    my $self = shift;
-    my %args = (
-        TimeTaken => 0,
-        Type      => undef,
-        OldValue  => undef,
-        NewValue  => undef,
-        Data      => undef,
-        Field     => undef,
-        MIMEObj   => undef,
-        ActivateScrips => 1,
-        CommitScrips => 1,
-        @_
-    );
-
-    require RT::Transaction;
-    my $trans = new RT::Transaction( $self->CurrentUser );
-    my ( $transaction, $msg ) = $trans->Create(
-        Ticket    => $self->Id,
-        TimeTaken => $args{'TimeTaken'},
-        Type      => $args{'Type'},
-        Data      => $args{'Data'},
-        Field     => $args{'Field'},
-        NewValue  => $args{'NewValue'},
-        OldValue  => $args{'OldValue'},
-        MIMEObj   => $args{'MIMEObj'},
-        ActivateScrips => $args{'ActivateScrips'},
-        CommitScrips => $args{'CommitScrips'},
-    );
-
-    # Rationalize the object since we may have done things to it during the caching.
-    $self->Load($self->Id);
-
-    $RT::Logger->warning($msg) unless $transaction;
-
-    $self->_SetLastUpdated;
-
-    if ( defined $args{'TimeTaken'} ) {
-        $self->_UpdateTimeTaken( $args{'TimeTaken'} );
-    }
-    if ( $RT::UseTransactionBatch and $transaction ) {
-	    push @{$self->{_TransactionBatch}}, $trans;
-    }
-    return ( $transaction, $msg, $trans );
-}
-
-# }}}
-
 =head2 TransactionBatch
 
   Returns an array reference of all transactions created on this ticket during
@@ -4204,6 +4100,54 @@
 }
 
 # }}}
+
+# }}}
+
+# {{{ sub Transactions 
+
+=head2 Transactions
+
+  Returns an RT::Transactions object of all transactions on this ticket
+
+=cut
+
+sub Transactions {
+    my $self = shift;
+
+    use RT::Transactions;
+    my $transactions = RT::Transactions->new( $self->CurrentUser );
+
+    #If the user has no rights, return an empty object
+    if ( $self->CurrentUserHasRight('ShowTicket') ) {
+        my $tickets = $transactions->NewAlias('Tickets');
+        $transactions->Join(
+            ALIAS1 => 'main',
+            FIELD1 => 'ObjectId',
+            ALIAS2 => $tickets,
+            FIELD2 => 'id'
+        );
+        $transactions->Limit(
+            ALIAS => $tickets,
+            FIELD => 'EffectiveId',
+            VALUE => $self->id()
+        );
+	$transactions->Limit(
+	    FIELD    => 'ObjectType',
+	    VALUE    => ref($self),
+	);
+
+        # if the user may not see comments do not return them
+        unless ( $self->CurrentUserHasRight('ShowTicketComments') ) {
+            $transactions->Limit(
+                FIELD    => 'Type',
+                OPERATOR => '!=',
+                VALUE    => "Comment"
+            );
+        }
+    }
+
+    return ($transactions);
+}
 
 # }}}
 

Modified: rt/branches/autrijus-3.1/lib/RT/User_Overlay.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/User_Overlay.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/User_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -58,80 +58,28 @@
 # {{{ sub _Accessible 
 
 
-sub _ClassAccessible {
+sub _OverlayAccessible {
     {
-     
-        id =>
-                {read => 1, type => 'int(11)', default => ''},
-        Name => 
-                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(120)', default => ''},
-        Password => 
-                { write => 1, type => 'varchar(40)', default => ''},
-        Comments => 
-                {read => 1, write => 1, admin => 1, type => 'blob', default => ''},
-        Signature => 
-                {read => 1, write => 1, type => 'blob', default => ''},
-        EmailAddress => 
-                {read => 1, write => 1, public => 1,  type => 'varchar(120)', default => ''},
-        FreeformContactInfo => 
-                {read => 1, write => 1, type => 'blob', default => ''},
-        Organization => 
-                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(200)', default => ''},
-        RealName => 
-                {read => 1, write => 1, public => 1, type => 'varchar(120)', default => ''},
-        NickName => 
-                {read => 1, write => 1, public => 1, type => 'varchar(16)', default => ''},
-        Lang => 
-                {read => 1, write => 1, public => 1, type => 'varchar(16)', default => ''},
-        EmailEncoding => 
-                {read => 1, write => 1, public => 1, type => 'varchar(16)', default => ''},
-        WebEncoding => 
-                {read => 1, write => 1, public => 1, type => 'varchar(16)', default => ''},
-        ExternalContactInfoId => 
-                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(100)', default => ''},
-        ContactInfoSystem => 
-                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(30)', default => ''},
-        ExternalAuthId => 
-                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(100)', default => ''},
-        AuthSystem => 
-                {read => 1, write => 1, public => 1, admin => 1,type => 'varchar(30)', default => ''},
-        Gecos => 
-                {read => 1, write => 1, public => 1, admin => 1, type => 'varchar(16)', default => ''},
-
-        PGPKey => {
-                {read => 1, write => 1, public => 1, admin => 1, type => 'text', default => ''},
-        },
-        HomePhone => 
-                {read => 1, write => 1, type => 'varchar(30)', default => ''},
-        WorkPhone => 
-                {read => 1, write => 1, type => 'varchar(30)', default => ''},
-        MobilePhone => 
-                {read => 1, write => 1, type => 'varchar(30)', default => ''},
-        PagerPhone => 
-                {read => 1, write => 1, type => 'varchar(30)', default => ''},
-        Address1 => 
-                {read => 1, write => 1, type => 'varchar(200)', default => ''},
-        Address2 => 
-                {read => 1, write => 1, type => 'varchar(200)', default => ''},
-        City => 
-                {read => 1, write => 1, type => 'varchar(100)', default => ''},
-        State => 
-                {read => 1, write => 1, type => 'varchar(100)', default => ''},
-        Zip => 
-                {read => 1, write => 1, type => 'varchar(16)', default => ''},
-        Country => 
-                {read => 1, write => 1, type => 'varchar(50)', default => ''},
-        Creator => 
-                {read => 1, auto => 1, type => 'int(11)', default => ''},
-        Created => 
-                {read => 1, auto => 1, type => 'datetime', default => ''},
-        LastUpdatedBy => 
-                {read => 1, auto => 1, type => 'int(11)', default => ''},
-        LastUpdated => 
-                {read => 1, auto => 1, type => 'datetime', default => ''},
 
- }
-};
+        Name                    => { public => 1,  admin => 1 },
+          Password              => { read   => 0,  admin => 1 },
+          EmailAddress          => { public => 1 },
+          Organization          => { public => 1,  admin => 1 },
+          RealName              => { public => 1 },
+          NickName              => { public => 1 },
+          Lang                  => { public => 1 },
+          EmailEncoding         => { public => 1 },
+          WebEncoding           => { public => 1 },
+          ExternalContactInfoId => { public => 1,  admin => 1 },
+          ContactInfoSystem     => { public => 1,  admin => 1 },
+          ExternalAuthId        => { public => 1,  admin => 1 },
+          AuthSystem            => { public => 1,  admin => 1 },
+          Gecos                 => { public => 1,  admin => 1 },
+          PGPKey                => { public => 1,  admin => 1 },
+
+    }
+}
+
 
 
 # }}}
@@ -1519,6 +1467,8 @@
     my %args = (
         Field => undef,
         Value => undef,
+	TransactionType   => 'Set',
+	RecordTransaction => 1,
         @_
     );
 
@@ -1538,7 +1488,19 @@
         Value => $args{'Value'}
     );
 
-    return ( $ret, $msg );
+    if ( $args{'RecordTransaction'} == 1 ) {
+
+        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+                                               Type => $args{'TransactionType'},
+                                               Field     => $args{'Field'},
+                                               NewValue  => $args{'Value'},
+                                               OldValue  => $self->SUPER::_Value("$args{'Field'}"),
+        );
+        return ( $Trans, scalar $TransObj->Description );
+    }
+    else {
+        return ( $ret, $msg );
+    }
 }
 
 # }}}
@@ -1588,6 +1550,9 @@
 
 # }}}
 
+sub CustomFieldValues {
+    # XXX
+}
 
 1;
 

Modified: rt/branches/autrijus-3.1/lib/RT/Users_Overlay.pm
==============================================================================
--- rt/branches/autrijus-3.1/lib/RT/Users_Overlay.pm	(original)
+++ rt/branches/autrijus-3.1/lib/RT/Users_Overlay.pm	Thu Mar  4 10:50:03 2004
@@ -76,6 +76,20 @@
 
 # }}}
 
+=head2 PrincipalsAlias
+
+Returns the string that represents this Users object's primary "Principals" alias.
+
+
+=cut
+
+sub PrincipalsAlias {
+    my $self = shift;
+    return($self->{'princalias'});
+
+}
+
+
 # {{{ sub _DoSearch 
 
 =head2 _DoSearch

Modified: rt/branches/autrijus-3.1/releng.cnf
==============================================================================
--- rt/branches/autrijus-3.1/releng.cnf	(original)
+++ rt/branches/autrijus-3.1/releng.cnf	Thu Mar  4 10:50:03 2004
@@ -1,5 +1,5 @@
 PRODUCT			        = rt
-TAG			            = 3.1.3
+TAG			            = 3.1.5
 CANONICAL_REPO		    = svn+ssh://svn.bestpractical.com/svn/bps-public/rt/
 TAGS		            = tags/
 TRUNK	                = branches/rt-3.1/

Modified: rt/branches/autrijus-3.1/sbin/rt-setup-database.in
==============================================================================
--- rt/branches/autrijus-3.1/sbin/rt-setup-database.in	(original)
+++ rt/branches/autrijus-3.1/sbin/rt-setup-database.in	Thu Mar  4 10:50:03 2004
@@ -87,10 +87,13 @@
         print "...skipped as ".$args{'dba'} ." is not " . $RT::DatabaseUser . " or we're working with Oracle.\n";
     }
 
-    $dbh->disconnect;
-    $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
-      || die $DBI::errstr;
+    
+    # SQLite can't deal with the disconnect/reconnect
+    unless ($RT::DatabaseType eq 'SQLite') {
 
+        $dbh->disconnect;
+        $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} ) || die $DBI::errstr;
+    }
     print "Now populating database schema.\n";
     insert_schema();
     print "Now inserting database ACLs\n";
@@ -111,7 +114,7 @@
     drop_db();
 }
 elsif ( $args{'action'} eq 'insert' ) {
-    insert_data( $args{'datafile'} );
+    insert_data( $args{'datafile'} || ($args{'datadir'}."/content"));
 }
 elsif ($args{'action'} eq 'acl') {
     $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
@@ -364,7 +367,7 @@
         exit(1);
     }
     print "done.\n";
-    $RT::Handle->Disconnect();
+    $RT::Handle->Disconnect() unless ($RT::DatabaseType eq 'SQLite');
 
 }
 
@@ -561,7 +564,7 @@
         }
         print "done.\n";
     }
-    $RT::Handle->Disconnect();
+    $RT::Handle->Disconnect() unless ($RT::DatabaseType eq 'SQLite');
 
 }
 

Modified: rt/branches/autrijus-3.1/sbin/rt-test-dependencies.in
==============================================================================
--- rt/branches/autrijus-3.1/sbin/rt-test-dependencies.in	(original)
+++ rt/branches/autrijus-3.1/sbin/rt-test-dependencies.in	Thu Mar  4 10:50:03 2004
@@ -97,7 +97,7 @@
 DBI 1.37
 Test::Inline
 Class::ReturnValue 0.40
-DBIx::SearchBuilder 0.95
+DBIx::SearchBuilder 0.97
 Text::Template
 File::Spec 0.8
 HTML::Entities 
@@ -116,6 +116,7 @@
 Text::Autoformat
 Text::Quoted 1.3
 Scalar::Util
+Module::Versions::Report
 .
 
 $deps{'MASON'} = [ _( << '.') ];
@@ -154,25 +155,25 @@
 .
 
 $deps{'FASTCGI'} = [ _( << '.') ];
-CGI
+CGI 2.92
 FCGI
 CGI::Fast 
 .
 
 $deps{'SPEEDYCGI'} = [ _( << '.') ];
-CGI
+CGI 2.92
 CGI::SpeedyCGI
 .
 
 
 $deps{'MODPERL1'} = [ _( << '.') ];
-CGI
+CGI 2.92
 Apache::Request
 Apache::DBI 0.92
 .
 
 $deps{'MODPERL2'} = [ _( << '.') ];
-CGI 2.89
+CGI 2.92
 Apache::DBI
 .
 

Added: rt/branches/autrijus-3.1/spec/schema.txt
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/spec/schema.txt	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,53 @@
+CF Schema redesign V5.
+======================
+
+TABLE CustomFields (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  Name varchar(200) NULL  ,
+  Type varchar(200) NULL  ,	# Changed -- 'Single' and 'Multiple' is moved out
+  MaxValues integer,		# New -- was 'Single'(1) and 'Multiple'(0)
+  Pattern varchar(255) NULL  ,	# New -- Must validate against this
+  ObjectType varchar(255) NOT NULL,		    # Final target of the Object
+  IntermediateType varchar(255) NOT NULL,	    # Intermediate type
+  ParentType varchar(255) NOT NULL,		    # Toplevel type
+  Description varchar(255) NULL  ,
+  SortOrder integer NOT NULL DEFAULT 0  ,   # not used!
+)
+
+TABLE ObjectCustomFields (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  CustomField int NOT NULL  ,		    # CustomField ID
+  ParentId integer NOT NULL,		    # Final id of toplevel parent, or the
+					    # object itself if ParentType is empty;
+					    # 0 means global as usual.
+  SortOrder integer NOT NULL DEFAULT 0  ,
+);
+
+TABLE ObjectCustomFieldValues (	# New -- Replaces TicketCustomFieldValues
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  CustomField int NOT NULL  ,
+  ObjectType varchar(255) NOT NULL,		    # Final target of the Object
+  ObjectId int NOT NULL  ,		    # New -- Replaces Ticket
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
+  Current BOOL DEFAULT '1',		    # New -- whether the value was current
+  Content varchar(255) NULL  ,
+  LargeContent LONGTEXT NULL,		    # New -- to hold 255+ strings
+  ContentType varchar(80) NULL,		    # New -- only text/* gets searched
+  ContentEncoding varchar(80) NULL  ,	    # New -- for binary Content
+)
+
+TABLE Transactions (
+  id INTEGER NOT NULL  AUTO_INCREMENT,
+  ObjectType varchar(255) NULL,		    # Final target of the Object
+  ObjectId integer NOT NULL DEFAULT 0  ,    # Changed -- was Ticket
+  TimeTaken integer NOT NULL DEFAULT 0  ,
+  Type varchar(20) NULL  ,
+  Field varchar(40) NULL  ,
+  OldValue varchar(255) NULL  ,
+  NewValue varchar(255) NULL  ,
+  ReferenceType varchar(255) NULL,	    # Currently "RT::OCFV" only
+  OldReference integer NULL  ,		    # New -- Id of ReferenceType
+  NewReference integer NULL  ,		    # New -- Id of ReferenceType
+  Data varchar(255) NULL  ,
+)

Added: rt/branches/autrijus-3.1/spec/spec.txt
==============================================================================
--- (empty file)
+++ rt/branches/autrijus-3.1/spec/spec.txt	Thu Mar  4 10:50:03 2004
@@ -0,0 +1,74 @@
+User/Group CF and Txn UI first.
+===============================
+Object<=>CF Edit interface; separate CFs into different kinds:
+    Currently only All-User, All-Group, All-Queue and some-Queue
+    To be created and picked on the "User->CF" and "Group->CF" tabs
+    use code from rtfm's ClassCustomFields as a base of ObjectCustomFields
+CF display for User and Group
+Binary CFs.
+Finish Txn display for User and Group
+ACL for per-CF editing
+    AdminThis ACL for CFs controls CF data and metadata, but _not_ where it applies
+    AdminCF ACL for Objects controls what CFs applies here, but _not_ CF's contents
+
+
+
+> As part of this work, Best Practical will provide a metadata system for
+> User and Groups akin to RT's current "CustomFields" system for tickets.
+> Best Practical will add new search functionality to allow CUSTOMER customer
+> support staff to search for users based on site-configurable metadata
+> about users and their organizations.
+> RT will be extended to track custom field changes on each type of object
+> that supports custom fields.
+> Best Practical will develop new user interface to display the history of
+> each User and Group object, including all changes to custom fields.
+> User Display
+> RT's User display will be enhanced to include display and editing of
+> custom fields, as well as display of group memberships.
+> Group Display
+> RT's Group display will be enhanced to include display and editing of
+> custom fields.
+
+The above goes together.  Highly interested.  2-3 weeks of work.  12k.
+
+> User and Group searching
+> The results of user and group searches will be downloadable as tab
+> delimited data, containing a list of columns to be specified at a later
+> time.
+
+I think you have done this already?  2 days of work, 1k.
+
+> Custom Field Functionality
+> Best Practical will extend RT's custom fields system to support
+> per-field access control.. Staff will be able to grant members of groups
+> as well as individual end-users the right to:
+> * See a custom field
+> * Edit a custom field's values for the object it applies to
+> * Manage a custom field
+>   Each Custom field that applies to users will be available for all
+> users
+>  Each Custom fields that applies to groups will be available for all
+> groups
+
+Quite interested. 2 weeks of work. 10k.
+
+> Custom fields will be extended to support several new data types:
+>         large freeform text
+>         uploaded documents, including images
+
+Trivial. 2 days of work, 1k.
+
+> Ticket Searching
+> RT's standard search functionality will be extended to support the
+> ability to find tickets that have a requestor who is a member of a
+> user-specified group.
+
+Trivial. 1 day of work, $500 or so.
+
+> Ticket Display
+> When viewing a ticket, RT currently displays a box containing metadata
+> about each requestor who is not a local staff member. Best Practical
+> will extend this box to list the requestor's group memberships.
+
+Not very interested. 2 days of work, 1k.
+



More information about the Rt-commit mailing list