2002-03-13  Mark Mitchell  <mark@codesourcery.com>

	* scripts/qm-release (build_rpm): Use sudo.
	(TAR_OPTS): Use "root" rather than "0" in owner options.

	* qm/test/cmdline.py (QMTest.MakeContext): Fix typo.
	* NEWS: Note fix.
	
2002-03-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/common.py (string_types): New variable.

	* qm/test/context.py: Permit Unicode strings throughout.
	* qm/test/result.py: Likewise.

2002-03-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/doc/tour.xml: Update tutorial instructions to reflect
	changes in QMTest 1.1.2.
	* qm/test/share/dtml/set-expectations.dtml: Clarify form.

	* configure.in (PYTHON_MAJOR): Robustify checks.
	(PYTHON_MINOR): Likewise.
	* configure: Regenerated.
	* qm/web.py (DocumentTemplate): Guard import with try-block to
	improve error messages.

2002-03-09  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/share/dtml/results.dtml: Simplify.
	* qm/test/web/web.py (StorageResultsStream.__init__): Initialize
	__test_results_in_order.
	(StorageResultsStream.WriteResult): Update it.
	(StorageResultsStream.Start): Likewise.
	(StorageResultsStream.GetTestResultsInOrder): New method.
	(TestResultsPage.__init__): Use it.
	(TestResultsPage.GetTotalUnexpected): Take advantage of the fact
	that test_results is now a list, not a dictionary.
	(TestResultsPage.GetResultsWithOutcome): Likewise.	
	(TestResultsPage.GetTestIds): Remove.

	* qm/test/web/web.py (StorageResultsStream.Start): Add test_ids
	parameter; remove existing results for tests that are going to be
	re-run.

	* qm/common.py (starts_with): Simplify.
	(ends_with): Likewise.
	(parse_assignment): New function.
	(read_assignments): Likewise.
	* qm/test/cmdline.py (context_file_name): New member.
	(QMTest.MakeContext): Use read_assignments.
	(QMTest.__ParseContextAssignment): Remove.
	(QMTest.__ParseKeywordArgument): Likewise.
	(QMTest.__ExecuteCreateTdb): Use parse_assignment.
	* qm/test/qmtest.py: Tidy interrupted message.
	* qm/test/share/dtml/load-expected-results.dtml: Remove.
	* qm/test/share/dtml/load-results.dtml: Likewise.
	* qm/test/share/dtml/load.dtml: New file.
	* qm/test/share/dtml/navigation-bar.dtml (load_context): New
	function.
	* qm/test/share/dtml/set-expectation.dtml: New file.
	* qm/test/web/web.py (QMTestPage.__init__): Add load context and
	save context functions to the file menu.
	(LoadExpectedResultsPage): Reimplement using load.dtml.
	(LoadResultsPage): Likewise.
	(LoadContxtPage): Likewise.
	(QMTestServer.__init__): Register context load and save URLs.
	(QMTestServer.HandleClearResults): Summarize the new results
	stream.
	(QMTestServer.HandleLoadContext): New method.
	(QMTestServer.HandleSaveContext): Likewise.
	(QMTestServer.HandleSubmitContext): Likewise.
	(QMTestServer._ClosePopupAndRedirect): New method.
	
	* COPYING: Replace with the GPL.
	Replace all other copyright notices with references to COPYING.
	* README: Note license change.
	
2002-03-06  Mark Mitchell  <mark@codesourcery.com>

	* GNUMakefile.in (PYTHON_PACKAGES): Remove sgmlop.
	* qm/attachment.py (AttachmentStore.HandleDownloadRequest): Update
	documentation.
	(AttachmentStore.Store): New method.
	(FileAttachmentStore.Store): Likewise.
	(TemporaryAttachmentStore.Add): Rename to ...
	(TemporaryAttachmentStore.Store): ... this.
	* qm/common.py (QMException): New class.
	(MethodShouldBeOverridenError): Derive from it.
	(MutexError): Likewise.
	(MutexLockError): Likewise.
	(ConfigurationError): Likewise.
	(UserError): Likewise.
	(load_class): Raise QMException, not ValueError.
	(make_temporary_directory): Remove FIXME.
	* qm/fields.py (SetField.FormatValueAsHtml): Tidy.
	(AttachmentField.FormatValueAsHtml): Likewise.
	(EnumerationField.MakePropertyControls): Likewise.
	* qm/platform_unix.py (RunProgramError): Derived from QMException.
	(SignalException): Likewise.
	* qm/web.py (qm_bug_system_url): Use the mailing list address.
	(WebServer.__init__): Register self._HandleProblems, not
	_handle_problems.
	(WebServer._HandleProblems): New method.
	(make_set_control): Remove counter manipulations.
	(make_button_for_popup): Don't cache it.
	(make_button_for_cached_popup): New function.
	(_handle_problems): Remove.
	* qm/xmultil.py (xml.dom.minidom): Import it.
	(load_xml): Use it.
	* qm/test/base.py (valid_id): Raise QMException, not RuntimeError.
	(load_database): Raise QMException, not ValueError.  Allow
	attributes to be passed to the database.
	(create_database): Allow attributes to be stored in the database
	configuration file.
	(get_extension_class): Turn ImportError into QMException.
	(load_results): Do not validate the incoming results file.
	* qm/test/cmdline.py (QMTest.attribute_option_spec): New member.
	(QMTest.Execute): Simplify exception-handling.
	(QMTest.__ParseContextAssignment): Break out ...
	(QMTest.__ParseKeywordArgument): ... this method.
	* qm/test/context.py (ContextException): New class.
	(Context.__getitem__): Raise it instead of KeyError.
	* qm/test/database.py (DatabaseError): Derived from QMException.
	(__init__): Do not require an attachment store.
	(Database.GetAttachmentStore): Require that it be overridden.
	* qm/test/file_database.py (FileDatabase.__init__): Remove the
	store parameter.
	* qm/test/qmtest.py (print_errror_message): Indent the message.
	* qm/test/result.py (Result.outcomes): Order from most 
	interesting to least interesting.
	* qm/test/target.py (Target.RunTest): Catch ContextException and
	introduce appropriate failure notices.
	* qm/test/test.py (Test.GetId): New method.
	* qm/test/text_result_stream.py (TextResultStream.Summarize): Tidy
	output.
	* qm/test/xmldb.py (Database.__init__): Do not pass down the
	attachment store.
	(Database.GetAttachmentStore): New method.
	* qm/test/classes/command.py (ExecTestBase): Robustify.
	* qm/test/share/dtds/tdb-configuration.dtd: Allow database
	attributes.
	* qm/test/share/dtml/dir.dtml: Rework display.
	* qm/test/share/dtml/navigation-bar.dtml: Simplify.
	* qm/test/share/dtml/result.dtml: Likewise.
	* qm/test/share/dtml/results.dtml: Rework display.
	* qm/test/share/messages/diagnostics.txt (invalid context
	assignment): Remove.
	(invalid keyword assignment): Add.
	(extension class not found): Likewise.
	* qm/test/web/web.py: Rework substantially.
	* scripts/.cvsignore: New file.
	* share/dtml/problems.dtml: Rework to mention mailing list.
	* share/web/common.js (property_add_or_change): Do not
	restrict to valid labels.
	* share/web/images/left-arrow.gif: New file.
	* share/web/stylesheets/qm.css: Update and extend.
	* qm/test/doc/reference.xml: Document -a option to create-tdb.

2002-02-15  Mark Mitchell  <mark@codesourcery.com>

	* qm/web.py (WebServer.Run): Remove exception-handling code.
	* qm/test/cmdline.py (QMTest.expectations_file_name): New
	variable.
	(QMTest.results_file_name): Likewise.
	* qm/test/share/dtml/load-expected-results.dtml: Use it.
	* qm/test/share/dtml/load-results.dtml: Likewise.
	* qm/test/share/dtml/navigation-bar.dtml (handle_menu_select): 
	Reset menus after use.
	* qm/test/web/web.py (QMTestPage.__init__): Use
	QMTest.expectations_file_name and QMTest.results_file_name.  Store
	the global QMTest object for DTML pages.
	(QMTestServer.__init__): Use QMTest.expectations_file_name and
	QMTest.results_file_name.

2002-02-13  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/command.py (Command.ExecTestBase.RunProgram):
	Make sure that result annotations are stored as strings, not 
	integers.

	* qm.spec.in (Release): Increment.

2002-02-13  Vladimir Prus <ghost@cs.msu.su>

	* qm/test/web.py (ShowSuitePage.__init__): Fix typo.
	* qm/test/file_database.py (FileDatabase._GetLabels): Likewise.
	
2002-01-29  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/result.py (Result.MakeDomNode): Fix typo.
	* qm/test/classes/temporary.py (TempDirectoryResource.__init__):
	Remove.
	(TempDirectoryResource.SetUp): Fix typo.
	(TempDirectoryResource.CleanUp): Likewise.
	
	* qm/test/database.py (ItemDescriptor._MakeItem): Tell a newly
	created test or resource what its name is.

	* qm/xmlutil.py (discard_node): Remove.
	* qm/test/xml_result_stream.py (XMLResultStream.WriteResult):
	Do not use it.
	* qm/test/qmtest.py: Remove Python 1.5 work-around.
	* qm/test/result.py: Alphabetize annotations in results file.
	
	* qm/test/cmdline.py (QMTest.MakeContext): Fix spelling of
	context file option.

2002-01-27  Mark Mitchell  <mark@codesourcery.com>

	* README (REQUIREMENTS): Note that Python 2.1 or higher
	is required.
	* README.sources: Remove restriction that software must work with
	Python 1.5.
	* configure.in: Check for Python 2.1 or higher.
	* configure: Regenerated.
	* qm/qm.sh (QM_PYTHON_FLAGS): New variable.
	(qm_python): Check /usr/bin/python2 before falling back to
	the python in the PATH.
	* qm/queue.py: Fix copyright notice.
	* qm/setup_path.py.in: Issue an error if an old version of
	Python is in use.
	* qm/trace.py: New file.
	* qm/test/cmdline.py (QMTest.__init__): Create a trace object.
	(QMTest.GetTracer): Return it.
	* qm/test/commnd_thread.py: Fix copyright notice.
	* qm/test/execution_engine.py: Likewise.
	(ExecutionEngine): Add trace message throughout.
	(ExecutionEngine._Trace): New method.
	* qm/test/target.py (Target.RunTest): Remove unnecessary code.
	* qm/test/doc/reference.xml: Update description of how QMTest
	locates the python interpreter to use.
	
2002-01-23  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (INSTALL_DIR): Set the mode of the installed
	directory.

2002-01-17  Mark Mitchell  <mark@codesourcery.com>

	* configure.in: Issue an error if distutils is not installed.
	* configure: Regenerated.
	* qm/test/doc/tour.xml: Update output display.	

	* GNUmakefile.in (SCRIPTS): Add $(SCRIPT_EXT).

2002-01-16  Mark Mitchell  <mark@codesourcery.com>

	* qm/structured_text.py: Substantial changes to support a verbatim
	markup.
	* qm/test/result.py (Result.AsStructuredText): Remove.
	* qm/test/text_result_stream.py (TextResultStream._DisplayResult): 
	Do not use it.
	* qm/test/classes/command.py (ExecTestBase): Change name of
	"Expected Standard Error" field to "Standard Error".
	(ExecTestBase.RunProgram): Use verbatim formatting for output
	and standard error annotations.
	* qm/test/doc/tour.xml: Update accordingly.
	* qm/test/share/dtml/result.dtml: Adjust formatting.
	* qm/test/web/web.py (TestResultsPage.FormatResult): Remove.
	(QMTestServer.HandleSaveResults): Fix typos.
	
2002-01-15  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/xmldb.py (Database.WriteSuite): Fix typo.
	* qm/test/classes/command.py (_make_result_for_exception): Remove.
	(ExecTestBase.RunProgram): Use execvpe, not execve.
	* qm/test/web/web.py (qm.test.suite): Import it.
	(QMTestServer.HandleCreateSuite): Pass the server, not the 
	test database, to ShowSuitePage.
	(QMTestServer.HandleShowSuite): Likewise.
	(QMTestServer.HandleSubmitSuite): Use Suite, not qm.test.base.Suite.

	* qm.spec.in (Release): Reset to zero.

	* scripts/qm-release (build_source): Change destination for
	PDF manual.

	* configure.in (QM_MINOR_VER): Increment.
	* configure: Regenerated.

	* scripts/qm-release (build_source): Correct copying of PDF
	documentation.

	* scripts/qm-release (build_source): Correct documentation 
	building.

	* GNUmakefile.in (lib-install): Correct installation location
	of classes.qmc.
	* qm/web.py (WebServer.handle_error): New method.

2002-01-07  Mark Mitchell  <mark@codesourcery.com>

	* configure.in: Do not build gadfly if it does not exist.

	* scripts/qm-release (build_source): Remove QMTrack from
	the release tarball.

	* NEWS: New file.
	
	* qm/queue.py: New file.
	* qm/test/base.py (get_extension_class_names_in_directory): Remove
	debugging statement.
	* qm/test/cmdline.py (web.web): Do not import it unconditionally.
	(QMTest.__ExecuteServer): Import it here.
	* qm/test/execution_engine.py (Queue): Do not import it.
	(qm.queue): Import it.
	(ExecutionEngine.__init__): Use qm.queue.Queue, not Queue.Queue.
	(ExecutionEngine.__CheckForResponse): Use qm.queue.Empty, not
	Queue.Empty.
	
	* qm/test/execution_engine.py (ExecutionEngine.Run): Pass 
	self to Target.Start.
	(ExecutionEngine._RunTests): Do not add untested results for
	tests that were not run if immediate termination was requested.
	(ExecutionEngine._AddResult): Do not assume that Result.TARGET
	will be present for all results.
	* qm/test/target.py (Target.Start): Add engine parameter.
	(Target.RunTest): Handle KeyboardInterrupts by stopping the
	execution engine.
	(Target._SetUpResource): Likewise.
	* qm/test/classes/rsh_target.py (RSHTarget.Start): Add engine
	parameter.
	* qm/test/classes/rsh_target.py (ThreadTarget.Start): Likewise.

	* qm/label.py (__label_regex): Add hyphens.
	(__label_regex_with_sep): Likewise.
	* qm/xmlutil.py (discard_node): Implement with
	xml.dom.ext.ReleaseNode.
	* qm/test/context.py (Context.ValidateKey): Allow hyphens.
	* qm/test/execution_engine.py (ExecutionEngine._RunTests): Keep
	the list of idle targets up to date.
	(ExecutionEngine._AddResult): Likewise.
	* qm/test/text_result_stream.py (TextResultStream._DisplayResult):
	Use XPASS and XFAIL where possible.
	(TextResultStream._WriteOutcome): New method.
	* qm/test/classes/ThreadTarget.py (TestResultStream.RunTest): Add
	assertions.
	* qm/test/share/messages/diagnostics.txt: Update documentation
	about labels.
	* qm/test/share/messages/help.txt: Likewise.
	* qm/track/share/messages/diagnostics.txt: Likewise.
	* qm/track/share/messages/help.txt: Likewise.
	* qm/test/doc/reference.xml: Likewise.
	* share/xml/.cvsignore: Add *.dtd.
	* configure.in (AC_PROG_MAKE_SET): Remove.

	* qm/test/share/dtds/result.dtd: Correct version number.

2002-01-06  Zack Weinberg  <zack@codesourcery.com>

	* GNUmakefile.in (PYTHON): Remove unnecessary use of 'env'.
	(clean): Don't use pushd and popd.  Don't delete documentation
	if we didn't build it.
	($(HTML_MANUALS)): Disable use of .tidyrc.
	* configure.in: Add Debian-specific locations of xml.dcl and
	DocBook stylesheets.  Fix typo.
	* configure: Regenerate.

2002-01-04  Mark Mitchell  <mark@codesourcery.com>

	* scripts/qm-release: New file.

2002-01-03  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (QM_TOOLS): Compute it automatically.

	* GNUmakefile.in (QM_TOOLS): New variable.
	(MAKEFILE_PRE_IN): Remove.
	(SCRIPTS): Calculate it automatically.
	(DTD_CATALOG): New variable.
	(COMMON_DTDS): Likewise.
	(TOOL_DTDS): Likewise.
	(COPIED_TOOL_DTDS): Likewise.
	(DTDS): Likewise.
	(JADECMD): Likewise.
	(DOCBOOK_MAIN): Remove.
	(DOCBOOK_SOURCES): Likewise.
	(HTMLDIR): Likewise.
	(HTMLINDEX): Likewise.
	(HTMLMANIFEST): Likewise.
	(HTMLTARBALL): Likewise.
	(PRINTDIR): Likewise.
	(PRINTTEX): Likewise.
	(PRINTPDF): Likewise.
	(HTML_MANUALS): New variable.
	(TEX_MANUALS): Likewise.
	(PDF_MANUALS): Likewise.
	(all): Add dependencies.
	(PYTHON_PACKAGES): Use -q option to setup.py.
	(DTD_CATALOG): New taret.
	(COPIED_TOOL_DTDS): Likewise.
	(clean): Clean up more stuff.
	(distclean): Remove GNUmakefile, not Makefile.
	(doc-html): Depend on HTML_MANUALS.
	(HTML_MANUALS): New rule.
	(TEX_MANUALS): Likewise.
	Adjust installation rules.
	* doc/qm-html.dsl: Rename to ...
	* doc/qm-sgml.dsl: ... this.
	* doc/qm-print.dsl: Rename to ...
	* doc/qm-tex.dsl: ... this.
	* doc/manual/introduction.xml: Remove.
	* doc/manual/manual.xml: Likewise.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.
	* doc/manual/track-email.xml: Likewise.
	* doc/manual/track-manual.xml: Likewise.
	* doc/manual/track-tour.xml: Likewise.
	* qm/.cvsignore: Add build.
	* qm/common.py (rmdir_recursively): Remove bogus assertion.
	(add_exit_function): Simplify.
	(_at_exit): Rename to ...
	(exit): This.
	* qm/diagnostic.py (load_messages): New function.
	(__initialize_module): Tweak.
	* qm/qm.sh: Fix typo in comment.
	* qm/setup.py: Automatically compute names of packages.
	* qm/setup_path.py.in: Add zope-dtml/ExtensionClass build
	directory to list of directories to search in build tree.
	* qm/test/.cvsignore: Remove qmtest-remote.
	* qm/test/cmdline.py (QMTest.commands_spec): Add "remote".
	(QMTest.Execute): Dispatch it.
	(QMTest.__ExecuteRemote): New method.
	* qm/test/qmtest-remote.py: Remove.
	* qm/test/qmtest.py: Use load_messages and qm.exit.
	* qm/test/classes/rsh_target.py (RSHTarget.Start): Use qmtest, not
	qmtest-remote, on the remote system.
	* qm/test/doc/.cvsignore: New file.
	* qm/test/doc/introduction.xml: Likewise.
	* qm/test/doc/manual.xml: Likewise.
	* qm/test/doc/reference.xml: Likewise.
	* qm/test/doc/tour.xml: Likewise.
	* qm/test/share/dtds/class-directory.dtd: New file.
	* qm/test/share/dtds/resource.dtd: Likewise.
	* qm/test/share/dtds/result.dtd: Likewise.
	* qm/test/share/dtds/suite.dtd: Likewise.
	* qm/test/share/dtds/target.dtd: Likewise.
	* qm/test/share/dtds/tdb-configuration.dtd: Likewise.
	* qm/test/share/dtds/test.dtd: Likewise.
	* qm/test/share/dtml/add-category.dtml: Likewise.
	* qm/test/share/dtml/add-prerequisite.dtml: Likewise.
	* qm/test/share/dtml/add-resource.dtml: Likewise.
	* qm/test/share/dtml/context.dtml: Likewise.
	* qm/test/share/dtml/dir.dtml: Likewise.
	* qm/test/share/dtml/expectations.dtml: Likewise.
	* qm/test/share/dtml/load-expected-results.dtml: Likewise.
	* qm/test/share/dtml/load-results.dtml: Likewise.
	* qm/test/share/dtml/navigation-bar.dtml: Likewise.
	* qm/test/share/dtml/new-suite.dtml: Likewise.
	* qm/test/share/dtml/new.dtml: Likewise.
	* qm/test/share/dtml/result.dtml: Likewise.
	* qm/test/share/dtml/results.dtml: Likewise.
	* qm/test/share/dtml/show.dtml: Likewise.
	* qm/test/share/dtml/suite.dtml: Likewise.
	* qm/test/share/messages/diagnostics.txt: Likewise.
	* qm/test/share/messages/help.txt: Likewise.
	* qm/test/share/tutorial/tdb/exec0.qmt: Likewise.
	* qm/test/share/tutorial/tdb/exec1.qmt: Likewise.
	* qm/test/share/tutorial/tdb/exec2.qmt: Likewise.
	* qm/test/share/tutorial/tdb/QMTest/configuration: Likewise.
	* qm/test/web/web.py (DefaultDtmlPage.__init__): New method.
	(QMTestServer.__Init__): Change path to manual.
	* qm/track/qmtrack.py: Use load_messages and qm.exit.
	* qm/track/server.py (WebServer.__init__): Change path to 
	manual.
	* qm/track/doc/.cvsignore: New file.
	* qm/track/doc/email.xml: Likewise.
	* qm/track/doc/introduction.xml: Likewise.
	* qm/track/doc/manual.css: Likewise.
	* qm/track/doc/manual.xml: Likewise.
	* qm/track/doc/reference.xml: Likewise.
	* qm/track/doc/tour.xml: Likewise.
	* qm/track/share/dtds/idb-configuration.dtd: Likewise.
	* qm/track/share/dtds/issue-classes.dtd: Likewise.
	* qm/track/share/dtds/issue.dtd: Likewise.
	* qm/track/share/dtds/user.dtd: Likewise.
	* qm/track/share/dtds/users.xml.template: Likewise.
	* qm/track/share/dtds/users.xml.test-values: Likewise.
	* qm/track/share/dtml/add-category-name.dtml: Likewise.
	* qm/track/share/dtml/add-issue-class.dtml: Likewise.
	* qm/track/share/dtml/add-issue-field.dtml: Likewise.
	* qm/track/share/dtml/add-notification-address.dtml: Likewise.
	* qm/track/share/dtml/add-notification-uid.dtml: Likewise.
	* qm/track/share/dtml/config-idb.dtml: Likewise.
	* qm/track/share/dtml/configuration-navigation-bar.dtml: Likewise.
	* qm/track/share/dtml/history.dtml: Likewise.
	* qm/track/share/dtml/index.dtml: Likewise.
	* qm/track/share/dtml/issue-class.dtml: Likewise.
	* qm/track/share/dtml/navigation-bar.dtml: Likewise.
	* qm/track/share/messages/diagnostics.txt: Likewise.
	* qm/track/share/messages/help.txt: Likewise.
	* share/diagnostics/test-help.txt: Remove.
	* share/diagnostics/test.txt: Remove.
	* share/diagnostics/track-help.txt: Remove.
	* share/diagnostics/track.txt: Remove.
	* share/dtml/test: Remove all files.
	* share/dtml/track: Likewise.
	* share/tutorial/test: Likewise.
	* share/xml/.cvsignore: New file.
	* share/xml/CATALOG: Remove.
	* share/xml: Remove all DTDs.
	* tests/unit.qms/test.qms/classes.qms/scripttest1.qmt: Fix 
	erroneous XML.
	
2002-01-02  Mark Mitchell  <mark@codesourcery.com>

	* .cvsignore (standard.mk): Remove.
	(Makefile): Likewise.
	(GNUmakefile): Ignore it.
	* Makefile.in: Rename to ...
	* GNUmakefile.in: ... this.
	* Makefile: New file.
	* standard.mk.in: Remove.
	* doc/.cvsignore (Makefile): Remove.
	* doc/Makefile.in: Remove.
	* doc/design/qmtest/.cvsignore (Makefile): Remove.
	* doc/manual/.cvsignore (Makefile): Remove.
	* doc/manual/Makefile.in: Remove.
	* doc/manual/track-manual.xml: Add user database description.
	* doc/manual/track-tour.xml: Update links.
	
	* qm/common.py (threading): Do not import it.
	(Lock): Remove.
	(MutexMixin): Likewise.
	* qm/test/cmdline.py (QMTest.__ExecuteRun): Use ExecutionEngine,
	not ExecutionThread.
	* qm/test/command_thread.py: New file.
	* qm/test/database.py (Database): Update documentation.
	* qm/test/execution_engine.py: New file.
	* qm/test/execution_thread.py (ExecutionThread): Move
	majority of contents to execution_engine.py.
	* qm/test/qmtest-remote.py (threading): Do not import it.
	* qm/test/target.py (CommandThread): Remove.
	* qm/test/xmldb.py (Database): Do not inherit from MutexMixin.
	Remove all references to locks and mutexes.
	* qm/test/classes/rsh_target.py (RSHTarget.NoteIdle): Remove.
	(RSHTarget._RecordResult): Mark the target idle when recording
	a test result.
	* qm/test/classes/thread_target.py (qm.test.command_thread):
	Import it.

	* standard.mk.in (TESTFLAGS): Remove.
	(test): Likewise.

2001-12-30  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py (AttachmentStore.GetSize): Provide a default
	implementation.
	(FileAttachmentStore): New class.
	* qm/common.py (load_class): Fix typo in error message.
	* qm/xmlutil.py (discard_node): New function.
	* qm/test/base.py (run_test): Remove.
	(set_up_resource): Likewise.
	(clean_up_resource): Likewise.
	* qm/test/cmdline.py (profile): Do not import it.
	(QMTest.profile_option_spec): Remove.
	(QMTest.GetTargets): Use SerialTarget if concurrent execution has
	not been requested.
	(QMTest.__ExecuteSummarize): Fix typo.
	(QMTest.__ExecuteRun): Improve keyboard interrupt handling.
	* qm/test/context.py (re): Import it.
	(Context.get): Fix typo.
	(Context.ValidateKey): Accept keys that include periods and
	underscores.
	(ContextWrapper.Get): Fix typo.
	* qm/test/database.py (ItemDescriptor._Execute): Allow the context
	to be None.
	(ResourceDescriptor.CleanUp): Do not take a context parameter.
	(Database.GetResource): Fix formatting.
	* qm/test/execution_thread.py: Rework substantially throughout.
	* qm/test/file_database.py (FileDatabase._GetLabels): Simplify.
	* qm/test/qmtest-remote.py: Rework for revised target interface.
	* qm/test/qmtest.py: Improve keyboard interrupt handling.
	* qm/test/resource.py (Resource.CleanUp): Do not take a context
	parameter.
	* qm/test/result.py (Result.RESOURCE): New constant.
	* qm/test/target.py (Target): Rework substantially.
	(CommandThread): Likewise.
	* qm/test/xmldb.py (Database.__init__): Remove create parameter.
	* qm/test/classes/classes.qmc: Add serial_target.SerialTarget.
	* qm/test/classes/rsh_target.py: Rework substantially.
	* qm/test/classes/temporary.py (TempDirectoryResource.SetUp): 
	Remember the path to the directory created.
	(TempDirectoryResource.CleanUp): Remove context parameter.
	* qm/test/classes/thread_target.py: Rework substantially.
	* qm/test/web/web.py (QMTestServer.__init__): Do not register
	a download URL if the database does not have an attachment
	store.
	* share/diagnostics/test.txt: Adjust documentation.
	* doc/test-manual.xml: Update description of context.
	
2001-12-13  Mark Mitchell  <mark@codesourcery.com>

	* qm.spec.in (Release): Increment.

2001-12-12  Mark Mitchell  <mark@codesourcery.com>

	* doc/test-manual.xml: Fix typo.

2001-12-12  Mark Mitchell  <mark@codesourcery.com>

	* PyXML/.cvsignore: New file.
	* doc/qm-opl.xml: Update copyright date.
	* doc/manual/common-manual.xml: Tweak language.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.
	* qm/test/classes/python.py (ExecTest.Run): Fix typo in comment.
	* share/dtml/set.dtml: Clarify help documentation.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* qm/web.py (make_button_for_popup): Spell "resizeable" without
	the "e" in JavaScript code.
	(format_user_id): Likewise.
	* share/dtml/help.dtml (popup_manual): Likewise.
	* share/web/common.js (show_help): Likewise.
	(popup_manual): Likewise.
	
	* share/dtml/test/result.dtml: Sort the annotations.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (doc-install): Do not assume $(INSTALL) understands
	wildcards.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (SCRIPTS): Use backslashes on Windows.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (install): Don't depend on install -D.
	(share-install): Likewise.
	* configure.in (AC_PROG_INSTALL): Remove.
	* configure: Regenerated.
	* standard.mk.in (INSTALL): Define explicitly.
	(INSTALL_DATA): Likewise.
	(INSTALL_PROGRAM): Likewise.
	(INSTALL_SCRIPT): Likewise.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (SCRIPTS): Hardwire destination path.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (PYTHON_PACKAGES_INSTALL): Do not attempt
	to set permissions on installed files.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (RELINCDIR): New variable.
	(PYTHON_PACKAGES_INSTALL): Use it.
	* standard.mk.in (INSTALLINCDIR): New variable.
	(NATPREFIX): Likewise.

	* Makefile.in (PYTHON_PACKAGES_INSTALL): Use relative paths.
	* README: Document Distutils version required.

	* Makefile.in (SCRIPTS): Fix typo.
	* qm.spec (Release): Increment.

	* Makefile.in (SCRIPTS): Generate files with DOS line-ending
	convention under Windows.
	* doc/manual/introduction.xml: Expand.
	* doc/manual/test-tour.xml: Explain that Cygwin will not work with
	QMTest.

2001-12-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py (TemporaryAttachmentStore.HandleUploadRequest):
	Add type attribute to <script>.
	* qm/web.py (DtmlPage.common_javascript): New variable.
	(DtmlPage.GenerateXMLHeader): New method.
	(DtmlPage.GenerateEndBody): Generate correctl XHTML.
	(DtmlPage.GenerateStartScript): New method.
	(DtmlPage.GenerateEndScript): Likewise.
	(WebRequest): Update extensions_map to map .js to text/javascript.
	(WebServer.__init__): Register "/common.js".
	(WebServer.TranslateRequest): Do not add a trailing '/' unless
	there is going to be something after the '/'.
	(make_set_control): Generate correct XHTML.
	(encode_set_control_contents): Likewise.
	(make_properties_control): Likewise.
	(make_help_link_html): Likewise.
	(make_popup_dialog): Likewise.
	(make_choose_control): Likewise.
	(_common_javascript): Remove.
	(_initialize_module): Likewise.
	* qm/test/web/web.py (QMTestPage.GenerateStartBody): Generate correct
	XHTML.
	* share/dtml: Likewise, for all files.
	* share/web/common.js (property_add_or_change): Change
	documentation text.
	(label_is_valid): Allow periods.
	* share/web/stylesheets/qm.css: Make sure it is valid CSS.
	
	* standard.mk.in (all): Remove doc.
	(doc): Rename to ...
	(doc-all): ... this.
	* doc/manual/Makefile.in (all): Depend on doc-all.
	* doc/manual/test-tour.xml: Clarify.
	* qm/platform_unix.py (find_in_path): Remove.
	(open_in_browser): Do not use it.
	* qm/web.py (WebServer.__init__): Point '/' at self._HandleRoot.
	(WebServer._HandleRoot): New method.
	(_handle_root): Remove.
	* qm/test/result.py (Result.AsStructuredText): Sort annotations.
	* qm/test/classes/python.py (ExecTest.Run): Give the expression
	for a failing test.
	* qm/test/web/web.py (QMTestServer._HandleRoot): Redirect '/' to
	'/test/dir'.
	* share/diagnostics/common.txt (browser error): Tidy.
	* share/dtml/help.dtml: Arrange for the manual to appear in a
	separate window.
	* share/web/common.js (show_help): Do not create the toolbar.
	* share/web/static/index.html: Remove.
	* share/xml/class-directory.dtd (class): Add target to the list
	of allowed class kinds.
	
	* configure.in (AC_OUTPUT): Do not create qm/Makefile.
	* configure: Regenerated.
	* scripts/qm-release (QM_INSTALL_DIR): Use an absolute path.

	* Makefile.in (SCRIPTS): Correct typo.
	* gadfly/.cvsignore: Remove.
	* scripts/qm-release: Remove empty directories manually.

	* Makefile.in (SCRIPTS): Generate them here.
	* qm/Makefile.in: Remove.
	* scripts/qm-release (build_source): Tell CVS not to export 
	empty directorieds.

	* Makefile.in: Completely rework installation logic.
	* README: Document requirement that GNU Make be used.
	* configure.in (AC_OUTPUT): Do not generate sgmlop/Makefile
	or zope-dtml/ExtensionClass/Makefile.
	* configure: Regenerated.
	* install-sh: Replace contents with the version that comes
	with autoconf.
	* install.py: Remove.
	* standard.mk.in (PYTHON): Add -O.
	(INSTALL_DATA): New variable.
	(INSTALL_DIR): Likewise.
	(INSTALL_PROGRAM): Likewise.
	(INSTALL_SCRIPT): Likewise.
	(SCRIPT_EXT): Likewise.
	(all): Use a double-colon rule.
	* qm/Makefile.in (SCRIPTS): Use SCRIPT_EXT.
	* qm/setup.py: New file.
	* qm/setup_path.py.in: Adjust for new installation location of
	PyXML.
	* qm/web.py (WebRequestHandler): Update extensions_map to
	map .css to text/css.
	* qm/test/classes/classes.qmc: List target classes.
	* scripts/qm-release: Adjust location of installation directory.
	Create tar files with appropriate modes and owners.
	* sgmlop/Makefile.in: Remove.
	* sgmlop/setup.py: List Python modules.
	* share/dtml/test/new-suite.dtml: Fix typo.
	* share/dtml/test/new.dtml: Likewise.
	* share/web/images/sc-logo.png: Remove.
	* xmlrpc/setup.py: New file.
	* zope-dtml/DocumentTemplate/setup.py: Likewise.
	* zope-dtml/ExtensionClass/Makefile.in: Remove.
	* zope-dtml/ExtensionClass/setup.py: Set ext_package.

2001-12-06  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/test-tour.xml: Tweak explanation of saving
	expectations.
	* qm/test/classes/command.py (ExecTestBase.RunProgram): Use
	execvpe to execute programs.
	
	* qm/test/web/web.py (QMTestServer.HandleSaveResults): Fix
	typos.

	* scripts/qm-release: Fix typo.
	
  	* scripts/qm-release: Update documentation copying rules. 

	* README: Remove stale link.
	* doc/manual/test-tour.xml: Fix typos.
	* qm/Makefile.in (SCRIPTS): Do not hard code prefix.
	* qm/test/cmdline.py: Do not import run.
	* scripts/qm-release (build_exec): New function.

2001-12-05  Mark Mitchell  <mark@codesourcery.com>

	* configure.in: Remove divert statements.

2001-12-05  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/command.py (ShellCommandTest): Use
	ShellCommandTest.command_shell, not just command_shell, as a
	context variable.
	(ShellScriptTest): Use ShellScriptTest.script_shell, not just
	script_shell.

2001-12-05  Mark Mitchell  <mark@codesourcery.com>

	* standard.mk.in (PRINTTEX): Fix -- problem with TeX formatting.
	* doc/qm.mod (dashdash): Remove FIXME comment.
	* doc/manual/common-manual.xml: Update.
	* doc/manual/text-manual.xml: Fix command-line reference.
	Spell-check.
	* doc/manual/test-tour.xml: Spell-check.
	* qm/cmdline.py (CommandParser.GetOptionsHelp): Tweak help
	string formatting.
	* qm/platform_unix.py (SignalException): Derive from
	RuntimeError.
	* qm/web.py (DtmlPage.GenerateHtmlHeader): Allow pages to
	insert additional headers.
	(WebServer.Run): Handle exceptions.
	(_handle_root): Fix typo.
	* qm/test/base.py (create_database): Raise a RuntimeError,
	not a ValueError, when something goes wrong.
	* qm/test/cmdline.py (Command._ExecuteRun): Create an
	ExecutionThread to run the tests.
	* qm/test/execution_thread.py: New file.
	* qm/test/run.py: Remove.
	* qm/test/web/web.py (DefaultDtmlPage.__init__): Remove
	menu logic.
	(DefaultDtmlPage.GenerateStartBody): Likewise.
	(DtmlPage): Rename to ...
	(QMTestPage): ... this.
	(QMTestPage.__init__): Include menu logic.
	(QMTestPage.GetServer): New method.
	(QMTestPage.GenerateStartBody): Likewise.
	(AddPrerequisitePage): Adjust to use QMTestPage.
	(AddResourcePage): Likewise.
	(ContextPage): Likewise.
	(DirPage): Likewise.
	(ExpectationsPage): Likewise.
	(LoadExpectedResultsPage): Likewise.
	(LoadResultsPage): Likewise.
	(NewItemPage): Likewise.
	(NewSuitePage): Likewise.
	(ResultPage): Likewise.
	(ShowItemPage): Likewise.
	(ShowSuitePage): Likewise.
	(StorageResultStream.__init__): Create lock to guard
	to __test_results and __resource_results.
	(TestResultsPage): Adjust to use QMTestPage.
	(QMTestServer): Pass server to page constructors.
	(QMTestServer.HandleStopTests): New method.
	* share/diagnostics/test.txt: Add execution terminated diagnostic.
	* share/dtml/test/results.dtml: Indicate incomplete vs.
	complete test results.
	* share/web/stylesheets/qm.css (span.warning): New class.
	
2001-11-29  Mark Mitchell  <mark@codesourcery.com>

	* doc/qm.mod (prompt): Reformat as >, not $.
	* doc/manual/test-tour.xml: Focus more attention on the graphical
	user interface.  Reorganize.
	* qm/fields.py (Field.GetHtmlHelp): Tweak message.
	* qm/web.py (qm_bug_system_url): Use qm.codesourcery.com, not
	qm.software-carpentry.com.
	* qm/test/classes/python.py (ExecTest): Tweak doc string.
	* share/dtml/test/results.dtml: Highligh unexpected results.
	* share/tutorial/test/tdb/exec1.qmt: Change this test so that
	it FAILs, rather than ERRORs.
	* share/web/stylesheets/qm.css (td.unexpected): Set
	background-color.
	(tr.fail): Change background-color.

2001-11-27  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (TestDescriptor.__init__): Correct
	documentation.
	* qm/test/test.py (TargetGroupField.GetDescription): Remove
	debugging statement.
	* qm/test/xmldb.py (Database.__MakeDomNodeForTest): Remove
	unncessary creation of target-group element.
	(Database.__ParseTestDocument): Do not restore it, either.
	(AttachmentStore.Adopt): Remove.
	* qm/test/web/web.py (QMTestServer.HandeSubmitItem): Remove
	category code.
	* share/dtml/test/show.dtml: Do not display categories.
	* share/xml/test.dtd: Remove target-group attribute.
	* qm/test/classes/command.py (ExecTestBase.RunProgram): Clarify
	error message.
	
	* PyXML/xml/parsers/xmlproc/xmlproc.py (XMLProcessor.parse_start_tag):
	Handle out-of-data condition correctly.

	* qm/test/base.py (get_class_arguments): Fix typo in comment.
	(get_class_description): 
	* qm/test/cmdline.py (Command): Rename to ...
	(QMTest): ... this.
	(_the_qmtest): New variable.
	(QMTest.__init__): Set it.
	(QMTest.GetTargets): Store the resulting list of targets.
	(get_qmtest): New function.
	* qm/test/database.py (Database.GetTestClasses): Rename to 
	...
	(Database.GetTestClassNames): ... this.
	(Database.GetResourceClasses): Rename to ...
	(Database.GetResourceClassNames): ... this.
	* qm/test/qmtest.py: Create a QMTest object, not a Command object.
	* qm/test/test.py (TargetGroupField): New class.
	(Test.arguments): Use it.
	* qm/test/web/web.py (NewItemPage.__init__): Adjust for Database
	method name changes.
	(NewItemPage.GetClassDescriptions): New method.
	(ShowItemPage.GetClassDescription): Use get_class_description.
	(ShowItemPage.GetBriefClassDescription): Likewise.
	(QMTestServer.MakeNewTest): Fix typo.
	(QMTestServer.MakeNewResource): Likewise.
	* share/diagnostics/test-help.txt: Update.
	* share/diagnostics/test.txt: Likewise.
	* share/dtml/problems.dtml: Remove references to Software Carpentry.
	* share/dtml/test/new.dtml: Update online help.
	* share/dtml/test/show.dtml: Improve resource formatting.
	
2001-11-21  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/web/web.py (FormatId): Add documentation.
	* share/dtml/test/result.dtml: Allow navigation on the
	test id.

2001-11-21  Mark Mitchell  <mark@codesourcery.com>

	* README: Document --prefix.  Remove getting started
	documentation.
	* README.sources: Remove obsolete information.  Document
	environment variable format.
	* doc/manual/test-manual.xml: Document environment variables
	used by QMTest.
	* qm/qm.sh: Use QM_PYTHON to find the Python interpreter if
	it is set.
	* qm/test/base.py (get_extension_directories): Change
	QMTEST_CLASSPATH to QMTEST_CLASS_PATH.
	* qm/test/text_result_stream.py (TextResultStream.__init__):
	Display "TEST RESULTS" heading.
	(TextResultStream.WriteResult): Display the
	result of the test immediately.
	(TextResultStream.Summarize): Use _DisplayHeading.
	(TextResultStream._SummarizeResults): Use _DisplayResult.
	(TextResultStream._DisplayResult): New method.
	(TextResultStream._DisplayHeading): Likewise.

2001-11-21  Jeffrey Oldham <oldham@codesourcery.com>
	    Ricardo Anguiano <anguiano@codesourcery.com>

	* README.sources: Fix typo.
	* doc/manual/test-manual.xml: Likewise.

2001-11-19  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (get_class_arguments): Retrofit to Python 1.5.2.

2001-11-19  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (install): Quote directory names.
	* install.py (scripts): Use .bat extension on Windows.
	(install_package): Include .pyd files on Windows.
	* qm/Makefile.in (SCRIPTS): Generate batch files under Windows.
	* qm/platform.py: Treat unknown platforms as UNIX.
	(get_shell_for_command): New function.
	(get_shell_for_script): Likewise.
	* qm/platform_unix.py (get_shell_for_command): Remove.
	(get_shell_for_script): Likewise.
	* qm/platform_win32.py (default_shell): New variable.
	* qm/test/suite.py (Suite.__init__): Remove unnecessary assertion.
	* qm/test/classes/command.py (ReadThread): New class.
	(WriteThread): Likewise.
	(ExecTestBase.exit_code): Revise documentation.
	(ExecTestBase.Run): Rename to ...
	(ExecTestBase.RunProgram): ... this.  Support Windows.
	(ExecTest.RunProgram): Rename to ...
	(ExecTest.Run): ... this.
	(ShellCommandTest.RunProgram): Rename to ...
	(ShellCommandTest.Run): ... this.
	(ShellScriptTest.RunProgram): Rename to ...
	(ShellScriptTest.Run): ... this.

2001-11-16  Mark Mitchell  <mark@codesourcery.com>

	* qm/web.py (WebServer.RegisterPathTranslation): Do not require
	the target path to be an extant directory.

2001-11-16  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (QM_SRPM): Remove target.
	* qm.spec.in: Make relocatable, use build root.

2001-11-16  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (QM_TAR_GZ): Modify logic.
	* install.py (bin_handler): Remove.

2001-11-15  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (QM_MAJOR_VER): New variable.
	(QM_MINOR_VER): Likewise.
	(QM_VERSION): Likewise.
	(QM_TAR_GZ): Likewise.
	(CVS_SERVER): Likewise.
	(CVS_REPOSITORY): Likewise.
	(CVS): Likewise.
	(RPM_ARCH): Likewise.
	(RPM_BASE): Likewise.
	(QM_RPM): Likewise.
	(QM_SRPM): Likewise.
	(dist): New target.
	(rpm): Likewise.
	(release): Likewise.
	* configure.in (QM_MAJOR_VER): Substitute it.
	(QM_MINOR_VER): Likewise.
	(QM_RELEASE_VER): Likewise.
	(QM_VERSION): Likewise.
	(DOCBOOK_DTD): Revisit logic.
	(AC_OUTPUT): Generate qm.spec.
	* configure: Regenerated.
	* qm.spec: Remove.
	* qm.spec.in: New file.

2001-11-15  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (check): New target.
	* doc/qm-html.dsl: Fix typo.
	* doc/manual/test-manual.xml: Update for simplifications below.
	* qm/test/base.py (get_class_arguments): New method.
	* qm/test/cmdline.py (Command.Execute): Fix thinko.
	* qm/test/context.py (Context.get): New method.
	(ContextWrapper.get): Likewise.
	* qm/test/database.py (ItemDescriptor.GetClassArguments): New
	method.
	(ItemDescriptor._MakeItem): Use it.
	* qm/test/resource.py (Resource.arguments): Update documentation.
	(Resource.__init__): Simplify.
	* qm/test/test.py (Test.arguments): Update documentation.
	(Test.__init__): Simplify.
	(Test.GetTargetGroup): Update.
	* qm/test/xmldb.py (Database.__GetArgumentsFromDomNode): Use
	get_class_arguments.
	* qm/test/classes/command.py: Update test classes.
	* qm/test/classes/file.py: Likewise.
	* qm/test/classes/python.py: Likewise.
	* qm/test/classes/temporary.py: Update resource classes.
	* qm/test/web/web.py (ShowItemPage.__init__): Update
	documentation.
	(QMTestServer.HandleSubmitItem): Use get_class_arguments.
	(QMTestServer.MakeNewTest): Use get_class_arguments.
	(QMTestServer.MakeNewResource): Use get_class_arguments.
	
2001-11-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/memory_issue_store.py (IssueStore.__Write): Store
	issues safely.  
	* qm/track/triggers/notification.py
	(NotifyFixedTrigger.property_declarations): New attribute.
	(NotifyFixedTrigger.GetRecipientAddresses): Handle empty list.
	(NotifyFixedTrigger.GetRecipientUids): Likewise.
	(NotifyByUidFieldTrigger.Preupdate): Use field_name property.

2001-11-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_unix.py (send_email): Reimplement, with support for
	attachments.

2001-11-09  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (TestDescriptor.GetTargetGroup): Robustify.

	* doc/manual/test-tour.xml: Clarify command sequence for running
	tests.
	* qm/common.py (find_program_in_path): Use the PATH environment
	variable if no path is specified.
	* qm/test/cmdline.py (Command.HasGlobalOption): Remove.
	(Command.Execute): Normalize the database path.
	* qm/test/database.py (TestDescriptor.__init__): Remove target_group
	parameter.
	(TestDescriptor.GetTargetGroup): Reimplement.
	* qm/test/qmtest.py (print_error_message): Tidy up the message.
	(program_name): Use only the basename.
	* qm/test/xmldb.py (Database.__ParseTestDocument): Correct typo.
	* qm/test/classes/Command.py (ExecTest.Run): Report the expected
	standard output when a test fails.  Do not use the "path"
	context variable.
	* qm/test/web/web.py (QMTestServer.MakeNewTest): Correct typos.
	(QMTestServer.MakeNewResource): Likewise.
	* share/diagnostics/test.txt: Reformat some error messages.
	
2001-11-08  Mark Mitchell  <mark@codesourcery.com>

	* COPYING: Fix typo.

2001-11-06  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/test-manual.xml: Fix typos.
	* qm/test/base.py (CommandFailedError): Remove.
	(Context): Remove.
	(ContextWrapper): Remove.
	(set_up_resource): Use Result.ACTION, not action, to 
	when constructing the result.
	(clean_up_resource): Likewise.
	* qm/test/cmdline.py (Command.commands_spec): Add -C and -c
	options to the GUI interface.
	(Command.GetTargets): Remove response_queue parameter.
	(Command.__ExecuteServer): Adjust.
	(Command.__ExecuteRun): Likewise.
	* qm/test/context.py: New file.
	* qm/test/qmtest-remote.py: Likewise.
	* qm/test/result.py (Result.ACTION): New constant.
	* qm/test/run.py (TestRun.Run): New method.
	(test_run): Remove.
	* qm/test/target.py (Target.__init__): Remove response_queue
	parameter.
	(Target.IsInGroup): New method.
	(Target.Start): Add response_queue parameter.
	* qm/test/classes/rsh_target.py (RSHThread._RunTest): Robustify.
	(RSHThread._SetUpResource): Likewise.
	(RSHThread._CleanUpResource): Likewise.
	(RSHThread._Stop): Likewise.
	(RSHTarget.__init__): Adjust documentation.
	(RSHTarget.Start): Add response_queue parameter.
	(ThreadTarget.__init__): Remove response_queue parameter.
	(ThreadTarget.Start): Add response_queue parameter.
	* qm/test/web/web.py (QMTestServer.__init__): Remove
	response_queue parameter.
	(QMTestServer.HandleRunTests): Use TestRun.
	
2001-11-05  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/test-manual.xml: Add command-line reference for
	"qmtest gui".
	* doc/manual/track-tour.xml: Fix typo.
	* qm/test/base.py (ItemDescriptor): Remove.
	(TestDescriptor): Likewise.
	(ResourceDescriptor): Likewise.
	(Suite): Likewise.
	* qm/test/cmdline.py (Command.commands_spec): Add -T and -j
	options to the GUI interface.
	(Command.GetTargets): New method.
	(Command.__ExecuteRun): Use it.  Adjust call to test_run.
	(Command.__ExecuteServer): Use GetTargest.
	* qm/test/database.py (ItemDescriptor): New class.
	(TestDescriptor): Likewise.
	(ResourceDescriptor): Likewise.
	* qm/test/directory_suite.py: Adjust module from which to import
	Suite.
	* qm/test/qmtest-remote.py: Simplify target creation.
	* qm/test/run.py (ProtocolError): Remove.
	(TargetSpec): Remove.
	(test_run): Accept Targets, not TargetSpecs.
	(load_target_specs): Remove.
	(_target_spec_from_dom): Remove.
	* qm/test/target.py (Target.__init__): Remove target_spec
	parameter and replace with several others.
	(Target.GetName): Adjust.
	(Target.GetGroup): Likewise.
	(Target.GetConcurrency): Likewise.
	(Target.GetProperties): Likewise.
	(Target.Start): New method.
	(CommandThread.run): Simplify dynamic dispatch.
	* qm/test/xmldb.py: Adjust for changes in locations of descriptors.
	* qm/test/classes/rsh_target.py (RSHTarget.__init__): Adjust
	to match changes to Target.__init__.
	(RSHTarget.Start): New method.
	(RSHTarget.Stop): Join the thread.
	* qm/test/classes/thread_target.py (ThreadTarget.__init__): Adjust
	to match changes to Target.__init__.
	(ThreadTarget.Start): New method.
	* qm/test/web/web.py (QMTestServer.__init__): Accept targets as
	a parameter.
	(QMTestServer.HandleRunTests): Use them.
	
	* qm/test/base.py (InstanceBase): Rename to ...
	(InstanceDescriptor): ... this.
	(TestDescriptor): Derive from InstanceDescriptor.
	(ResourceDescriptor): Likewise.
	(extension_kinds): Add "target".
	* qm/test/cmdline.py: Use "ThreadTarget" not "SubprocessTarget".
	* qm/test/qmtest-remote.py: Adjust for reworking of target
	machinery.
	* qm/test/run.py (CommandThread): Remove.
	(Target): Likewise.
	(LocalThread): Likewise.
	(SubprocessTarget): Likewise.
	(RemoteThread): Likewise.
	(RemoteShellTarget): Likewise.
	(TestRun.Schedule): Simplify.
	(TestRun.AddResult): Likewise.
	(TestRun.__TargetIsReady): Remove.
	(test_run): Simplify.
	* qm/test/target.py: New file.
	* qm/test/classes/rsh_target.py: Likewise.
	* qm/test/classes/thread_target.py: Likewise.
	
2001-10-29  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/resource.py: New file.

	* doc/manual/test-manual.xml: Fix typo.
	* qm/test/base.py (InstanceBase.__init__): Remove properties
	parameter.
	(InstanceBase.SetProperty): Remove.
	(InstanceBase.GetProperty): Remove.
	(InstanceBase.GetProperties): Likewise.
	(InstanceBase.MakeItem): Add target_group parameter.
	(TestDescriptor.__init__): Adjust accordingly.
	(TestDescriptor.GetTargetGroup): New method.
	(ResourceDescriptor.__init__): Remove properties parameter.
	* qm/test/run.py (Target.Stop): Adjust comment.
	(SubprocessTarget.Stop): Remove assertion.
	(RemoteShellTarget.Stop): Likewise.
	(TestRun.Schedule): Use GetTargetGroup, not properties, to 
	get the tests target group.
	(TestRun.GetTestResults): Remove.
	(TestRun.GetResourceResults): Remove.
	(TestRun.__ValidateTest): Always check the target group.
	(TestRun.__FindBestTarget): Adjust documentation.  Simplify
	handling of target groups.
	(test_run): Adjust documentation.  Do not return results.
	Terminate targets in the event of an exception.
	* qm/test/test.py: Fix comments.
	(Test.arguments): Add target_group field.
	(Test.__init__): Adjust accordingly.
	(Test.GetTargetGroup): New method.
	* qm/test/xmldb.py (Database.__ParseTestDocument): Retrieve
	the target group.  Do not look for properties.
	(Database.__ParseResourceDocument): Likewise.
	(Database.__MakeDomNodeForItem): Do not write out properties.
	* qm/test/classes/command.py (ExecTest.arguments): Include
	Test.arguments.
	(ExecTest.__init__): Adjust accordingly.
	(ShellCommandTest.__init__): Likewise.
	(ShellScriptTest.__init__): Likewise.
	* qm/test/classes/file.py (FileContentsTest): Derived from Test.
	(FileContentsTest.arguments): Include Test.arguments.
	(FileContentsTest.__init__): Adjust accordingly.
	* qm/test/classes/python.py (ExecTest.arguments): Include
	Test.arguments.
	(ExecTest.__init__): Adjust accordingly.
	(BaseExceptionTest.arguments): Include Test.arguments.
	(BaseExceptionTest.__init__): Adjust accordingly.
	(ExceptionTest.arguments): Include Test.arguments.
	(BaseExceptionTest.__init__): Adjust accordingly.
	* qm/test/classes/temporary.py (TempDirectoryResource): Derive
	from Resource.
	* qm/test/web/web.py (QMTestServer.HandleSubmitItem): Do not
	deal with properties.
	* share/dtml/test/show.dtml: Remove properties handling.
	* share/xml/resource.dtd: Remove properties.
	* share/xml/test.dtd: Likewise.  Add target-group.
	
	* qm/test/qmtest.py: Remove the first directory from sys.path.
	
2001-10-28  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/track-manual.xml: Revise section on issue IDs.
	* doc/manual/track-tour.xml: Likewise.
	* qm/track/cmdline.py (Command.__PerformCreate): Assign issue
	IDs automatically.
	(Command.__HandleServerOptions): Add default_port parameter.
	(Command.__PerformConfigureIdb): By default, only allow
	connections from localhost.
	* qm/track/issue_class.py (IssueClass.__init__): Add next_id
	parameter.  Make the iid field hidden.
	(IssueClass.AllocateNextId): New method.
	(IssueClass.MakeDomNode): Write out the next available ID.
	(from_dom_node): Read it back in.
	* qm/track/web/show.py (handle_submit): Assign issue IDs 
	automatically.
	* share/diagnostics/track.txt: After creating an issue database,
	tell the user how to configure it.
	* share/xml/issue-classes.dtd (issue-class): Add next-id
	attribute.
	
2001-10-27  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/test-manual.xml: Note that -D is no lnoger required.
	* doc/manual/test-tour.xml: Likewise.
	* qm/test/cmdline.py (Command.Execute): If no database is
	specified, assume the database is in the current directory.
	* qm/test/xmldb.py (GetResource): Fix typo.
	* qm/test/web/web.py (DirPage.__init__): Do not show implicit
	test suites.
	(DirPage.MakeRunUrl): New method.
	* share/dtml/test/dir.dtml (run_dir): New method.
	
	* qm/.cvsignore: Add *.pyo.
	* qm/test.cvsignore: Likewise.
	* qm/test/classes/.cvsignore: Likewise.
	* qm/test/web/.cvsignore: Likewise.
	* qm/track/.cvsignore: Likewise.
	* qm/track/triggers/.cvsignore: Likewise.
	* qm/track/web/.cvsignore: Likewise.
	
	* qm/test/base.py (InstanceBase.__init__): Take 'database' as a
	parameter.
	(TestDescriptor.__init__): Likewise.
	(ResourceDescriptor.__init__): Likewise.
	(Suite.__init__): Likewise.
	(Suite.GetAllTestAndSuiteIds): New method.
	(get_suite_contents_recursively): Remove.
	(expand_ids): Likewise.
	(get_database): Likewise.
	(load_database): Return the new database.
	(get_extension_directories): Take the database as a parameter.
	(get_extension_class_names): Likewise.
	(get_test_class): Likewise.
	(get_resource_class): Likewise.
	(make_new_test): Remove.
	(make_new_resource): Likewise.
	(_database): Remove.
	* qm/test/cmdline.py (Command.Execute): Remember the newly loaded
	database.
	(Command.GetDatabase): Adjust.
	* qm/test/database.py (Database.GetTestClasses): Adjust
	call to get_extension_class_names.
	(Database.GetResourceClasses): Likewise.
	(Database.ExpandIds): New method.
	* qm/test/directory_suite.py (DirectorySuite.__init__): Take
	the database as a parameter.
	* qm/test/run.py (Target.__init__): Take the database as
	a parameter.
	(SubprocessTarget.__init__): Likewise.
	(RemoteShellTarget.__init__): Likewise.
	(TestRun.__init__): Likewise.
	(test_run): Likewise.
	(_send): Remove.
	(_receive): Likewise.
	* qm/test/text_result_stream.py (TextResultStream.__init__): Take
	the database as a parameter.
	* qm/test/xmldb.py (Database): Adjust for removal of global
	database variable.
	* qm/test/web/web.py: Likewise.
	
2001-10-26  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/manual.xml (track-email): New entity.
	* doc/manual/track-manual.xml: Reference it (but commented out).
	* doc/manual/track-email.xml: New file.
	
2001-10-20  Mark Mitchell  <mark@codesourcery.com>

	* qm/doc/manual/common-manual.xml: Adjust configuration file
	description.
	* qm/test/base.py (load_outcomes): Take a file object, not a path. 
	* qm/test/cmdline.py (Command.__ExecuteRun): Adjust.
	(Command.__ExecuteSummarize): Likewise.
	* qm/test/web/run.py (TestResultsPage): Take expected_outcomes
	as a parameter.
	* qm/test/web/show.py (ShowPage.__init__): Adjust menu item
	handling.
	* qm/test/web/suite.py (ShowPage.__init__): Adjust menu item
	handling.
	* qm/test/web/web.py (DefaultDtmlPage.__init__): Add menu items
	for loading and saving expectations.
	(ExpectationsPage): New class.
	(LoadExpectedResultsPage): Likewise.
	(QMTestServer.__init__): Add support for loading and saving
	expectations.
	(QMTestServer.GetExpectedOutcomes): New method.
	(QMTestServer.HandleEditExpectations): Likewise.
	(QMTestServer.HandleLoadExpectedResults): Likewise.
	(QMTestServer.HandleSaveExpectations): Likewise.
	(QMTestServer.HandleRunTests): Pass expected outcomes to
	TestResultsPage.
	(QMTestServer.HandleSubmitExpectations): New method.
	(QMTestServer.HandleSubmitExpectationsForm): Likewise.
	* qm/share/dtml/test/expectations.dtml: New file.
	* qm/share/dtml/test/load-expected-results.dtml: Likewise.
	* qm/share/dtml/test/navigation-bar.dtml (handle_menu_select): 
	Simplify menu handling.
	
2001-10-19  Mark Mitchell  <mark@codesourcery.com>

	* qm/doc/test-manual.xml: Update for changes to GUI.
	* qm/test/base.py (load_outcomes): Adjust for changes to ...
	(load_results): ... this function.  Take a file object, not
	a path, as input.  Return one combined sequence of all results.
	* qm/test/cmdline.py (Command.__ExecuteSummarize): Adjust
	accordingly.
	* qm/test/web/web.py (DefaultDtmlPage): Add loading and
	saving results to the file menu.
	(LoadResultsPage): New class.
	(QMTestServer.__init__): Add support loading and saving
	results.
	(QMTestServer.HandleLoadResults): New method.
	(QMTestServer.HandleSaveResults): Likewise.
	(QMTestServer.HandleSubmitResults): Likewise.
	* share/dtml/test/load-results.dtml: New file.
	* share/dtml/test/navigation-bar.dtml: Add support for
	loading results.
	* share/web/common.js: Fix HTML.
	
	* qm/web.py (DtmlPage.MakeMenuItem): New method.
	(WebRequestHandler): Print thank you message when shutting down.
	(WebServer.Bind): Remove getsockname call.
	* qm/test/web/show.py (ShowPage.__init__): Add menu items.
	(ShowPage.MakeEditUrl): New method.
	(ShowPage.MakeRunUrl): Likewise.
	(ShowPage.MakeDeleteScript):  Fix comment.
	* qm/test/web/suite.py (ShowPage.__init__): Add menu items.
	(ShowPage.MakeEditUrl): New method.
	(ShowPage.MakeRunUrl): Likewise.
	(ShowPage.MakeDeleteScript):  Fix comment.
	* qm/test/web/web.py (DefaultDtmlPage.__init__): Set up menu
	items.
	(DefaultDtmlPage.GenerateStartBody): Provide the menu items to
	the navigation bar.
	(QMTestServer.__init__): Handle show-results.  Store results
	permanently.
	(QMTestServer.HandleRunTests): Treat an empty set of test
	ids as the "." test suite.  Use HandleShowResults to implement
	results display.
	(QMTestServer.HandleShowResults): New method.
	* share/dtml/test/dir.dtml: Rework for menus.
	* share/dtml/test/navigation-bar.dtml: Likewise.
	* share/dtml/test/results.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/dtml/test/suite.dtml: Likewise.
	
	* qm/platform_win32.py (open_in_browser): Implement.

2001-10-19  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/test-manual.xml (sec-specifying-test-class): Update.

2001-10-19  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py (_get_db_configuration_directory): Rename to...
	(get_db_configuration_directory): ... this.
	Update accordingly throughout.
	* qm/test/database.py (Database.GetClassPaths): Rewrite.
	* qm/test/xmldb.py (Database.GetClassPaths): Use base class
	implementation. 

2001-10-19  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (load_xml_file): Don't handle exceptions here.
	* qm/web.py (WebRequestHandler.do_POST): Expand fields here.
	(WebRequestHandler.__HandleXmlRpcRequest): Dump exception if
	verbose. 
	(parse_form_query): Remove.
	* qm/structured_text.py (StructuredTextProcessor.NormalizeSpaces):
	Remove FIXME.  Expand tabs.
	(__entity_char_regex): Remove FIXME.
	* qm/platform.py (open_in_browser): Remove.
	* qm/platform_win32.py (open_in_browser): Remove.
	* qm/platform_unix.py (get_user_name): Reimplement.
	* qm/fields.py (Field.MakePropertyControls): Remove FIXME.
	(TextField.CompareValues): Likewise.
	* qm/common.py (RcConfiguration): Remove FIXME.
	(format_traceback): Likewise.
	(find_program_in_path): Use os.pathsep.  Use is_executable.
	(is_executable): Rewrite.
	(split_argument_list): Remove FIXME.
	(parse_time): Change FIXME to note.
	* qm/track/server.py (_script_base): Remove FIXME.
	* qm/track/issue_database.py (open): Remove FIXMEs.
	* qm/track/cmdline.py (Command.__PerformCreate): Remove FIXME.
	(Command.__PerformCreateIdb): Likewise.
	(Command.__ImportIssues): Likewise.
	* qm/track/web/query.py (QueryPage.MakePythonQueryHelp): Remove
	FIXME. 
	(QueryPage.MakeCategorySelect): Likewise.
	(QueryPage.MakeStateSelect): Likewise.
	* qm/track/web/issue_class.py: Remove FIXME.
	(handle_submit_class): Remove FIXME.  Don't try to handle new
	issue classes here.
	* qm/track/triggers/notification.py
	(NotifyFixedTrigger.GetSubscriberAddresses): Remove FIXME.
	(NotifyByUidFieldTrigger.GetSubscriberAddresses): Likewise. 
	* qm/test/result.py (Result.MakeDomNode): Update comment.
	* qm/test/cmdline.py (Command.tdb_class_option_spec): New
	attribute. 
	(Command.commands_spec): Add create-tdb.  Alphabetize.
	(Command.Execute): Reorganize.  Handle create-tdb.
	(Command.__ExecuteCreateTdb): New. 
	(Command.__ExecuteRun): Remove FIXME.
	* qm/test/base.py (dtds): Add tdb-configuration.
	(_get_db_configuration_directory): New function.
	(_get_db_configuration_path): Likewise.
	(is_database): Likewise.
	(load_database): Use them.
	(create_database): Change database directory semantics.
	(_result_from_dom): Remove FIXME.
	* qm/test/web/web.py (QMTestServer.HandleRunTests): Remove FIXME.
	* qm/test/classes/command.py (make_result_for_exception): Rename
	to... 
	(_make_result_for_exception): ... this.  Comment it.
	Update accordingly throughout.
	* share/xml/tdb-configuration.dtd (class_name): Rename to...
	(class-name): ... this.
	* share/diagnostics/common.txt (xmlrpc exception): New
	diagnostic. 
	* share/diagnostics/test.txt (new db message): Likewise
	(not test database): Likewise.
	* doc/manual/test-manual.xml (sec-testcmd-create-tdb): New
	section. 
	(sec-reg-writing-database-classes): Update.
	* doc/manual/test-tour.xml (sec-testtut-setting-up): Likewise.
	* tests/QMTest: New directory.
	* tests/QMTest/configuration: New file.

2001-10-18  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/run.py (CommandThread.__init__): Initialize Queue
	in a way that works with Python 1.5.2.
	(test_run): Likewise.

	* qm/test/result.py (Result.GetCause): New function.
	(Result.keys): Fix typo.
	* qm/test/web/run.py (TestResultsPage): Do not derived from
	ResultStream.
	(TestResultsPage.GetOutcomes): New function.
	(TestResultsPage.GetTotal): Likewise.
	(TestResultsPage.GetTotalUnexpected): Likewise.
	(TestResultsPage.GetResultsWithOutcome): Likewise.
	(TestResultsPage.GetCount): Likewise.
	(TestResultsPage.GetUnexpectedCount): Likewise.
	(TestResultsPage.GetRelativeResults): Likewise.
	(TestResultsPage.GetDetailUrl): Likewise.
	* qm/test/web/web.py (ResultPage): New class.
	(StorageResultsStream): Likewise.
	(QMTestServer.HandleRunTests): Use it.
	(QMTestServer.HandleShowResult): New function.
	* share/dtml/test/result.dtml: New file.
	* share/dtml/test/results.dtml: Revise.

2001-10-18  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Mention quotes for string literals.

2001-10-17  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (SetField.__init__): Fix typo in comment.

	* qm/web.py (make_properties_control): Sort the keys.  Pass
	more information to JavaScript functions.
	* qm/test/cmdline.py (Command._ExecuteServer): Use QMTestServer,
	not make_server.
	* qm/test/web/dir.py (DirPage.__init__): Add the "." suite at
	the top level.
	* qm/test/web/run.py (handle_run_tests): Remove.
	* qm/test/web/web.py (make_server): Turn into ...
	(QMTestServer): ... new class.
	(handle_shutdown): Turn into ...
	(QMTestServer.HandleShutdown): ... this.
	(ContextPage): New class.
	* qm/share/dtml/test/context.dtml: New file.
	* qm/share/dtml/test/dir.dtml: Add "Edit Context" button.
	* qm/share/web/common.js (property_add_or_change): Clear
	the name/value fields after an addition.
	(property_remove): Likewise.

2001-10-16  Mark Mitchell  <mark@codesourcery.com>

	* install.py: Install the class manifest.

	* qm/async.py: Remove.
	* qm/common.py (parse_time): Handle Windows format for GMT.
	* qm/qm.sh: Handle qmtest-remote correctly.
	* qm/test/base.py (set_up_resource): Fix typo.
	(clean_up_resource): Likewise.
	* qm/test/qmtest-remote.py: Rework to avoid use of qm.async.
	* qm/test/run.py (CommandThread): New class.
	(Target.GetChannels): Remove.
	(Target.EnqueueRunTest): Use EnqueueCommand, not _EnqueueCommand.
	(Target.EnqueueSetUpResource): Likewise.
	(Target.EnqueueCleanUpResource): Likewise.
	(Target.OnReplyReady): Rename to ...
	(Target.OnReply): ... this.  Rework.
	(LocalThread): New class.
	(SubprocessTarget): Use it throughout.
	(RemoteThread): New class.
	(RemoteShellTarget): Use it throughout.
	(RemoteDemultiplexerTarget): Remove.
	(TestRun.AddTestResult): Fold with ...
	(TestRun.AddResourceResult): ... into ...
	(TestRun.Result): ... this.
	(test_run): Adjust.
	(process_commands): Remove.
	* qm/test/classes/command.py (ExecTest): Adjust file closing
	for exception safety.

2001-10-14  Mark Mitchell  <mark@codesourcery.com>

	* qm/share/web/stylesheets/qm.css: Modify to work with Internet
	Explorer.

	* qm/web.py (WebServer.TranslateRequest): Use os.path.isabs
	for robustness.

	* qm/common.py (RcConfiguration.__Load): Do not crash if the
	HOME environment variable is not defined.

	* doc/manual/common-manual.xml: Revise.
	* doc/manual/manual.xml: Likewise.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-reference.xml: Remove.
	* doc/manual/test-tour.xml: Revise.
	* doc/manual/track-tour.xml: Revise.
	* doc/manual/track-reference.xml: Merge into...
	* doc/manual/track-manual.xml: ... here.
	
2001-10-13  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/manual.xml (track-reference): New entity.
	Reference it.
	* doc/manual/track-manual.xml (sec-qmtrack-configuration): New
	section.
	* doc/manual/track-reference.xml: New file.
	
2001-10-13  Alex Samuel  <samuel@codesourcery.com>

	* configure.in (DOCBOOK_DTD): Look for it in the standard place.
	* configure: Regenerate.

2001-10-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (FieldPropertyDeclaration): Rename to...
	(PropertyDeclaration): ... this.
	Adjust accordingly throughout.
	* qm/track/server.py (make_server): Use
	handle_shutdown_by_administrator. 
	(handle_shutdown): Rename to...
	(handle_shutdown_by_administrator): ... this.
	(handle_shutdown): New function.
	* qm/track/issue_database.py (setup_for_test): Use
	SetSubscriptionCondition. 
	* qm/track/issue_class.py (Trigger.class_name): New variable.
	(Trigger.property_declarations): Likewise.
	(Trigger.__init__): Rewrite.
	(Trigger.GetProperty): New method.
	(Trigger.SetProperty): Likewise.
	(Trigger.GetName): Use GetProperty.
	(Trigger.MakeDomNode): New method.
	(StateField.property_declarations): Adjust for
	PropertyDeclaration. 
	(IssueClass.GetField): Fix error code.
	(IssueClass.MakeDomNode): Store triggers.
	(trigger_from_dom_node): New function.
	(from_dom_node): Load triggers.
	* qm/track/triggers/state.py (Trigger.class_name): New variable.
	(Trigger.property_declarations): Likewise.
	(Trigger.__init__): Pass propertis to parent.  Don't use object
	attributes. 
	(Trigger.Preupdate): Use GetProperty.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.property_declarations): New variable.
	(_NotifyTrigger.__init__): Pass properties to parent.  Don't use
	object attributes.
	(_NotifyTrigger.GetCondition): Use GetProperty.
	(_NotifyTrigger.SetFromAddress): Use SetProperty.
	(_NotifyTrigger.SetSubjectPrefix): Use GetProperty.
	(_NotifyTrigger.Postupdate): Likewise.
	(NotifyFixedTrigger.class_name): New variable.
	(NotifyFixedTrigger.__init__): Pass properties to parents.  Don't
	use object attributes.
	(NotifyFixedTrigger.GetSubscriberAddresses): Use user database.
	(NotifyFixedTrigger.SetRecipientAddresses): New method.
	(NotifyFixedTrigger.GetRecipientAddresses): Use GetProperty.
	(NotifyFixedTrigger.SetRecipientUids): new method.
	(NotifyFixedTrigger.GetRecipientUids): Use GetProperty.
	(NotifyFixedTrigger.AddRecipientAddress): Use GetRecipientAddress
	and SetRecipientAddress.
	(_NotifyByFieldTrigger.property_declarations): New variable.
	(_NotifyByFieldTrigger.__init__): Pass properties to parent.
	Don't use object attributes.
	(_NotifyByFieldTrigger.GetFieldName): New method.
	(_NotifyByFieldTrigger.GetFieldContents): Use it.
	(NotifyByAddressFieldTrigger.class_name): New variable.
	(NotifyByAddressFieldTrigger.__init__): Pass properties to
	parent.  Don't use object attributes.
	(NotifyByUidFieldTrigger.class_name): New variable.
	(NotifyByUidFieldTrigger.property_declarations): Likewise.
	(NotifyByUidFieldTrigger.__init__): Pass properties to parent.
	Don't use object attributes.
	(NotifyByUidFieldTrigger.SetAutomaticSubscription): Rename to...
	(NotifyByUidFieldTrigger.SetSubscriptionCondition): ... this.
	(NotifyByUidFieldTrigger.GetAutomaticSubscriptionCondition):
	Rename to...
	(NotifyByUidFieldTrigger.GetSubscriptionCondition): ... this.
	(NotifyByUidFieldTrigger.Preupdate): Use accessor.
	* qm/track/triggers/discussion.py (DiscussionTrigger.class_name):
	New variable. 
	(DiscussionTrigger.property_declarations): Likewise.
	(DiscussionTrigger.__init__): Pass properties to parent.  Don't
	use object attributes.
	(DiscussionTrigger.Preupdate): Use GetProperty.
	* qm/track/web/issue_class.py (handle_submit_subscription): Use
	SetSubscriptionCondition. 
	* share/dtml/track/config-idb.dtml: Add shutdown button.
	* share/xml/issue-classes.dtd (issue-class): Add triggers.
	(trigger): New element.

2001-10-12  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/introduction.xml: Revise.
	* doc/manual/manual.xml: Likewise.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.
	* qm/test/cmdline.py (Command.db_path_option_spec): Change
	--db-path to --tdb.
	(Command.start_browser_option_spec): Remove.
	(Command.no_browser_option_spec): New variable.
	(Command.commands_spec): Adjust summarize command syntax.
	Rename server to gui.
	* qm/test/text_result_stream.py (TextResultSream.Summarize): Tweak.
	* qm/test/classes/file.py (FileContentsTest.Run): Fix typo.
	* share/diagnostics/test-help.txt: Revise description of
	test classes.
	* share/dtml/test/new.dtml: Revise.
	* share/tutorial/test/tdb/exec1.qmt: Right code that throws an 
	exception, rather than simply computing an incorrect value.
	* share/tutorial/test/tdb/_classes/count.py: Revise for new test
	class API.
	
2001-10-11  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (set_up_resource): Set up the action
	annotation when the result is created.
	* qm/test/base.py (clean_up_resource): Likewise.
	* qm/test/cmdline.py (Command.__ExecuteRun): Use unbufferred
	output for the results file.
	* qm/test/result.py (Result.__init__): Correct handling of
	default parameter.
	* qm/test/classes/command.py (Command.Run): Fix typos.
	
	* qm/test/base.py (base.dtds): Change version number for
	result DTD.
	(write_results): Remove.
	(save_results): Likewise.
	(_test_results_from_dom): Likewise.
	(_resource_results_from_dom): Likewise.
	(load_results): Adjust.
	(_result_from_dom): Likewise.
	(_count_outcomes): Rename to ...
	(count_outcomes): ... this.
	(summarize_test_stats): Remove.
	(summarize_relative_test_stats): Likewise.
	(summarize_test_suite_stats): Likewise.
	(summarize_results): Likewise.
	(run_test): Indicate that the new result is for a test.
	(set_up_resource): Indicate that the new result is for a resource.
	(clean_up_resource): Likewise.
	* qm/test/cmdline.py (Command.__ExecuteSummarize): Use 
	TextResultStream.
	(Command.__ExecuteRun): Likewise.  Use XMLResultStream.
	(Command.__ProgressCallback): Remove.
	(Command.__SummarizeResults): Remove.
	(Command.__WriteResults): Remove.
	* qm/test/file_database.py: Tweak documentation.
	* qm/test/result.py (Result.RESOURCE): New constant.
	(Result.TEST): Likewise.
	(Result.kinds): New variable.
	(Result.__init__): Add kind parameter.
	(Result.GetKind): New method.
	(Result.MakeDomNode): Write out kind attribute.
	* qm/test/result_stream.py: New file.
	* qm/test/run.py (TestRun.__init__): Take result_streams,
	not progress_function, as a parameter.
	(TestRun.AddTestResult): Call __ReportResult, not
	__ProgressMessage.
	(TestRun.AddResourceResult): Likewise.
	(TestRun.__ReportResult): New function.
	(TestRun.__ProgressMessage): Remove.
	(test_run):  Take result_streams, not message_function, as a
	parameter.
	* qm/test/text_result_stream.py: New file.
	* qm/test/xml_result_stream.py: Likewise.
	* qm/test/web/run.py (TestResultsPage): Inherit from ResultStream.
	(TestResultsPage.__init__): Adjust.
	(TestResultsPage.WriteResult): New method.
	(TestResultsPage.Summarize): Likewise.
	(handle_run_tests): Adjust.
	* qm/test/web/show.py: Fix typo.
	* qm/test/web/web.py: Likewise.
	* share/xml/CATALOG: Update result.dtd version.
	* share/xml/result.dtd: Remove test-results and resource-results
	elements.
	
2001-10-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (InstanceBase): Tweak documentation.
	(InstanceBase.GetClass): Use TestDescriptor, not Test, and
	ResourceDescriptor, not Resource.
	(Test): Rename to TestDescriptor.
	(Resource): Rename to ResourceDescriptor.
	(make_new_test): Adjust.
	(make_new_resource): Likewise.
	* qm/test/xmldb.py (Database.__ParseTestDescriptor): Likweise.
	(Database.__ParseResourceDescriptor): Likewise.
	* qm/test/web/show.py (handle_sumbit): Likewise.
	
	Use 'arguments' not 'fields' in test classes.
	Change API for 'Run' method in tests.
	* qm/test/base.py: Import qm.test.result.
	(standard_test_class_names): Remove.
	(standard_resource_class_names): Likewise.
	(InstanceBase.__MakeItem): Use 'arguments', not 'fields'.
	(Test.Run): Take result parameter.
	(Resource.SetUp): Likewise.
	(Resource.CleanUp): Likewise.
	(Resource.__Do): Likewise.
	(Result): Remove.
	(ResultWrapper): Remove.
	(make_result_for_exception): Likewise.
	(make_new_test): Use arguments, not fields.
	(make_new_resource): Likewise.
	(write_results): Adjust documentation.
	(save_results): Likewise.
	(load_results): Likewise.
	(_test_results_from_dom): Likewise.
	(_result_from_dom): Construct a Result, not a ResultWrapper.
	(split_results_by_expected_outcome): Adjust documentation.
	(summarize_relative_test_stats): Likewise.
	(summarize_test_suite_stats): Likewise.
	(summarize_results): Likewise.
	(run_test): Adjust for new API.
	(set_up_resource): Likewise.
	(clean_up_resource): Likewise.
	* qm/test/cmdline.py (Command): Adjust documentation.
	(Command.__SummarizeResults): Tweak.
	* qm/test/result.py: New file.
	* qm/test/run.py (TestRun): Adjustments throughout to use
	Result instead of ResultWrapper.
	* qm/test/test.py: New file.
	* qm/test/xmldb.py (Database.__GetArgumentsFromDomNode): Use
	arguments, not fields.
	(Database.__MakeDomNodeForItem): Likewise.
	* qm/test/command.py: Adjustments throughout.
	* qm/test/file.py: Likewise.
	* qm/test/python.py: Likewise.
	* qm/test/temporary.py: Likewise.
	* qm/test/web/run.py (TestResultsPage.__init__): Adjust
	documentation.
	(TestResultsPage.FormatResult): Likewise.
	* qm/test/web/show.py (ShowPage.AddPrerequisitePage): Tweak.
	(handle_submit): Likewise.
	
	* qm/test/base.py (InstanceBase.GetClass): Use
	get_extension_class.
	(load_databse): Likewise.
	(get_extension_directories): Add kind parameter.
	(get_extension_class_names_in_directory): New function.
	(get_extension_class_names): Likewise.
	(get_extension_class): Likewise.
	(get_test_class): Likewise.
	(get_resource_class): Likewise.
	(get_class): Remove.
	(make_new_test): Use get_test_class.
	(make_new_resource): Use get_resource_class.
	(__loaded_classes): Remove.
	(__builtin_class_path): Likewise.
	(extension_kinds): New variable.
	(__class_caches): Likewise.
	* qm/test/database.py (GetTestClasses): Use 
	get_extension_class_names.
	(GetResourceClasses): Likewise.
	* qm/test/run.py (SubprocessTarget.__init__): Fix typo in comment.
	* qm/test/xmldb.py (Database.__ParseTestDocument): Use get_test_class.
	(Database.__ParseResourceDocument): Use get_resource_class.
	* qm/test/classes/__init__.py: Remove.
	* qm/test/classes/classes.qmc: New file.
	* qm/test/web/show.py (handle_show): Use get_extension_class.
	(handle_submit): Likewise.
	* share/xml/CATALOG: Add class-directory.dtd.
	* share/xml/class-directory.dtd: New file.
	
2001-10-07  Mark Mitchell  <mark@codesourcery.com>

	* qm/label.py (MakeRelativeTo): Rename to ...
	(AsAbsolute): ... this.
	(UnmakeRelativeTo): Rename to ...
	(AsRelative): ... this.
	* qm/test/base.py (Suite.IsImplicit): Update comment.
	(ResultWrapper.AsStructuredText): Fix thinko.
	* qm/test/database.py (Database.GetSuite): Update documentation.
	(Database.HasSuite): Likewise.
	(Database.GetSubdirectories): New method.
	(Database.GetTestClasses): Fix typo.
	(Database.GetResourceClasses): Fix typo.
	* qm/test/file_database.py (FileDatabase.GetSubdirectories): New
	method.
	(FileDatabase._GetLabels): Use AsAbsolute, not MakeRelativeTo.
	* qm/test/web/dir.py (DirItem): Remove.
	(DirPage.__init__): Store subdirectories, tests, suites, and
	resources.
	(handle_dir): Use the 'id' attribute to figure out which directory
	to display.
	* qm/test/web/show.py (NewItemPage.__init__): Use
	Database.GetResourceClasses.
	* qm/test/web/web.py (FormatId): Handle '.' specially.
	(make_server): Register 'show-dir'.
	* qm/test/share/dtml/test/dir.dtml: Rework for hierarchical
	directory display.
	* qm/share/dtml/test/suite.dtml: Remove bogus commentary about
	implicit suites.

2001-10-06  Mark Mitchell  <mark@codesourcery.com>

	* qm/label.py (to_path): Add extension parameter.
	* qm/test/base.py (Suite.GetTestIds): Revise documentation.
	(Suite.GetSuiteIds): Likewise.
	* qm/test/database.py (NoSuchTestError.__str__): Fix typo.
	(NoSuchSuiteError.__str__): Likewise.
	(NoSuchResourceError.__str__): Likewise.
	(Database): Update documentation.
	(Database.GetTestIds): Add scan_subdirs parameter.
	(Database.GetSuite): Update documentation.
	(Database.HasSuite): Likewise.
	(Database.GetSuiteIds): Add scan_subdirs parameter.
	(Database.GetResourceIds): Likewise.
	* qm/test/directory_suite.py: New file.
	* qm/test/file_database.py: Likewise.
	* qm/test/xmldb.py (test_file_extension): Remove.
	(suite_file_extension): Likewise.
	(resource_file_extension): Likewise.
	(Database): Inherit from FileDatabase.
	(Database.__init__): Adjust accordingly.
	(Database.GetTest): Rename and modify to become ...
	(Database._GetTestFromPath): ... this.
	(Database.GetTestIds): Remove.
	(Database.GetSuite): Rename and modify to become ...
	(Database._GetSuiteFromPath): ... this.
	(Database.GetSuiteIds): Remove.
	(Database.GetResource): Rename and modify to become ...
	(Database._GetResourceFromPath): ... this.
	(Database.GetResourceIds): Remove.
	(DirectorySuite): Remove.
	(AttachmentStore.__init__): Add database parameter.
	(AttachmentStore.__MakeDataFilePath): Use it to get the spellings
	of the various attachments.
	
	* qm/test/xmldb.py (Database.__init__): Pass the attachment
	store down to the base class.
	(Database.GetAttachmentStore): Remove.
	(Database.__GetArgumentsFromDomNode): Use GetAttachmentStore
	to access the attachment store.

2001-10-05  Mark Mitchell  <mark@codesourcery.com>

	* README.sources: Fix typo.

	* qm/label.py: Revise documentation.

	* qm/test/base.py: Move Database to ...
	* qm/test/database.py: New file.
	* qm/test/cmdline.py: Use it throughout in place of base.
	* qm/test/qmtest-remote.py (program_name): Fix initialization.
	* qm/test/qmtest.py (program_name): Likewise.
	* qm/test/xmldb.py: Import database.  Use it throughout in place
	of base.
	* qm/test/web/show.py: Likewise.
	* share/diagnostics/test.txt (no such resource): New error message.
	
	* qm/structured_text.py (HtmlFormatter.FinishDefinedTerm):
	Write the <dd> tag corresponding to the beginning of the
	definition itself.
	* qm/test/base.py (ResultWrapper.AsStructuredText): New method.
	(summarize_results): Use it.
	* qm/test/web/run.py (TestResultsPage.ShouldShowProperty): Remove.
	(TestResultsPage.FormatProperty): Remove.
	(TestResultsPage.FormatResult): New method.
	* share/dtml/test/results.dtml: Update accordingly.

	* qm/test/base.py (Database.__init__): New method.
	(Database.GetPath): Return the stored value.
	* qm/test/cmdline.py (Command.Execute): Convert the database
	path to an absolute path, if it isn't already one.
	* qm/test/xmldb.py (Database.__init__): Call the base class
	initializer.  Don't store path.
	(Database.GetClassPaths): Use GetPath, not __path, to retrieve
	the database path.
	(Database.GetPath): Remove.

2001-10-04  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (SUBDIRS): Add doc.
	(install): Change invocation of install.py.
	(clean): New target.
	* configure.in (AC_OUTPUT): Add qm/setup_path.py.
	* configure: Regenerated.
	* install.py: Rework generation of scripts.
	* standard.mk.in (.PHONY): Add clean.
	* doc/manual/Makefile.in (clean::): New rule.
	* qm/Makefile.in (setup_path.py): Remove rule.
	(SCRIPTS): Simplify.
	* qm/attachment.py: Fix formatting.
	* qm/qm.sh: New file.
	* qm/test/qmtest-remote.in: Rename to ...
	* qm/test/qmtest-remote.py: ... this.
	* qm/test/qmtest.in: Rename to ...
	* qm/test/qmtest.py: ... this.
	* qm/track/qmtrack.in: Rename to ...
	* qm/track/qmtrack.py: ... this.
	* sgmlop/Makefile.in (clean): Use double-colon rule.
	* zope-dtml/ExtensionClass/Makefile.in (clean): Likewise.
	
2001-10-04  Alex Samuel  <samuel@codesourcery.com>

	* README: Mention test suite.

2001-10-04  Alex Samuel  <samuel@codesourcery.com>

	* unit.qms/test.qms/classes.qms/scripttest3.qmt: Update.
	* unit.qms/track.qms/export.qms/export1.qmt: Remove obsolete test.
	* unit.qms/track.qms/export.qms/export2.qmt: Likewise.
	* unit.qms/track.qms/export.qms/setup_idb.qmt: Likewise.
	* unit.qms/track.qms/export.qms/idb.qma: Remove action.

2001-10-04  Mark Mitchell  <mark@codesourcery.com>

	* qm/web.py (WebServer.__init__): Document meaning of using
	0 as the port.
	(WebServer.Bind): Handle port 0 specially.
	* qm/test/cmdline.py (Command.__ExecuteServer): Use port 0
	as the default port and 127.0.0.1 as the default address
	for the web server.
	* qm/test/web/web.py (make_server): Do not provide a default
	argument for address.

2001-10-03  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py: Attempt to fix formatting.

2001-10-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.GetValueFromDomNode): Rename store parameter
	to attachment_store.
	Likewise for all subclasses.
	(from_dom_node): Likewise.  Pass it recursively.
	* qm/track/memory_issue_store.py (IssueStore.UpdateIssueClass):
	Fix brackets.
	(open): Add attachment_store parameter.
	* qm/track/issue_database.py (AttachmentStore.__init__): Call base
	class __init__.
	(AttachmentStore.Store): Accept None for issue.
	(AttachmentStore.Adopt): Remove.
	(AttachmentStore.StoreFromFile): New method.
	(_IssueDatabase.UpdateIssueClass): New function.
	(open): Open the attachment store first, and pass it to the issue
	store open function.
	* qm/track/issue.py (get_issues_from_dom_node): Add
	attachment_store parameter.
	(_get_field_values_from_dom_node): Likewise.
	(get_issue_from_dom_node): Likewise.
	(get_issue_difference_from_dom_node): Likewise.
	(get_histories_from_dom_node): Likewise.
	(get_history_from_dom_node): Likewise.
	(load_issue_histories): Likewise.
	* qm/track/issue_class.py (from_dom_node): Likewise.
	(load): Likewise.
	* qm/track/cmdline.py (Command.__PerformCreate): Use correct
	module for Issue.
	(Command.__PerformConfigureIdb): Call web_server.Run directly.
	* qm/track/web/web.py (store_attachment_data): New function.
	* qm/track/web/issue_class.py (handle_submit_field): Call
	store_attachment_data for attachment field default values.
	(handle_new_class): Use idb.GetConfiguration.
	* qm/track/web/show.py (handle_new): Likewise.
	Use correct module for Issue.
	(handle_submit): Likewise.
	(_store_attachment_data): Remove.

2001-10-03  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Clarify blank lines.
	* qm/track/test.py: Remove.
	* qm/track/web/issue_class.py: Remove spurious import.

2001-10-02  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/command.py (ShellCommandTest): Fix typo in comment.

	* qm/fields.py (SetField.GetValueFromDomNode): Correct thinko.

	* qm/test/classes/command.py (ExecTest.fields): Adjust
	documentation for environment.
	(ExecTest.MakeEnvironment): Include the contents of the current
	environment.
	* doc/manual/test-reference.xml: Note change.

	* doc/manual/test-reference.xml: Add section on writing database
	classes.

	* qm/test/base.py (load_database): Rework.
	(get_extension_directories): New function.
	(get_class): Use it.
	(get_database_class): New function.
	* share/xml/tdb-configuration.dtd: New file.
	* share/xml/CATALOG: Add it.

	* qm/common.py (rmdir_recursively): Remove the directory itself.

	* qm/attachment.py (TemporaryAttachmentStore): Derived from
	AttachmentStore.  Add all_stores variable.
	(AttachmentStore.__init__): Add the new store to all_stores.
	(AttachmentStore.GetIndex): New method.
	(TemporaryAttachmentStore.__init__): Initialize the base
	class.
	(TemporaryAttachmentStore.Add): Close the file after the
	data has been written out.
	(Attachment): Include a reference to the associated attachment 
	store.
	(Attachment.__init__): Take an attachment store as a parameter.
	(Attachment.__cmp__): Compare the attachment store along with
	the other fields.
	(AttachmentWrapper): Remove.
	(from_dom_node): Add attachment store parameter.
	(get_attachment_store): New function.
	* qm/common.py (make_unique_tag): Return something more likely
	to be unique.
	(_unique_tag): New variable.
	* qm/fields.py (Field.FromDecodeValue): Adjust comment.
	(UploadAttachmentPage.__init__): Fix typo in comment.  Put the
	attachment store into the context for the DTML page.
	(AttachmentField.FromEncodeValue): Encode the attachment store.
	(AttachmentField.FormDecodeValue): Decode the attachment store
	value.
	* qm/test/base.py (InstanceBase.__MakeItem): Remove special
	handling for attachments.
	(Database.WriteTest): Update comments.
	* qm/test/web/show.py (_retrieve_attachment_data): Remove.
	(handle_submit): Remove special handling for attachments.
	Remove temporary attachments when they are no longer needed.
	* qm/test/web/web.py (make_server): Fix typo in comment.
	* qm/track/server.py (_make_server): Fix typo in comment.
	* share/dtml/attachment.dtml: Encode the attachment store
	when returning information to the server.
	
2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/cmdline.py (Command.__SummarizeResults): Only show
	resource results section if there are some failing.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/cmdline.py (Command.__SummarizeResults): Always show
	non-relative stats in full format.
	* tests/unit.qms/track.qms/export.qms/export2.qmt: Fix.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field): Rename __attributes to __properties
	throughout. 
	(Field.GetAttribute): Rename to...
	(Field.GetProperty): ... this.
	(Field.SetAttribute): Rename to...
	(Field.SetProperty): ... this.	
	(Field.GetAttributeNames): Rename to ...
	(Field.GetPropertyNames): ... this.
	(Field.IsAttribute): Rename to...
	(Field.IsProperty): ... this.
	Adjust accordingly throughout.
	* qm/track/issue_class.py (StateField.GetStateModel): Use
	GetProperty. 
	(StateField.SetStateModel): Use SetProperty.
	* qm/test/base.py (ContextWrapper): Rename attributes to
	properties throughout.
	* qm/test/web/show.py (ShowPage.FormatFieldValue): Use IsAttribute.
	* qm/test/classes/file.py (SubstitutionField.__init__): Rename
	attributes to properties.
	(SubstitutionField): Rename path_attribute to path_property
	throughout. 
	* qm/track/cmdline.py (Command.__PrintResults): Likewise.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.__MakeMessage): Likewise. 
	* qm/track/web/show.py (ShowPage.IsShowField): Likewise.
	(ShowPage.FormatFieldValue): Likewise.
	* qm/track/web/summary.py (DisplayOptionsPage.__init__): Likewise.
	* qm/track/web/issue_class.py (handle_submit_subscription): Use
	SetProperty.
	* share/dtml/track/issue-class.dtml: Use IsAttribute.
	* share/dtml/track/subscription.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/diagnostics/test.txt 
	(context attribute cannot be deleted): Rename to ...
	(context property cannot be deleted): ... this.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/classes/file.py (SubstitutionField.class_name): New
	attribute. 
	(SubstitutionField.GetHelp): Fix link in help text.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/issue_class.py (IssueClass.__init__): Adjust field
	descriptions. 
	* qm/track/cmdline.py (Command.GetIdbPath): Fix exception.
	(run_command): Handle IdbError.
	* qm/track/qmtrack.in: Load diagnostics.
	* qm/track/server.py: Remove obsolete import.
	* qm/track/web/query.py: Likewise.
	* qm/test/classes/command.py (ExecTest.fields): Fix description of
	exit_code field. 
	* share/dtml/track/show.dtml: Show brief field descriptions when
	editing. 
	* share/dtml/test/show.dtml: Fix indentation.
	* share/diagnostics/track.txt (idb locked): Adjust.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/classes/command.py (ExecTest.Run): Open input files for
	read. 

2001-09-27  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (Database.GetTestClasses): New method.
	* qm/test/web/show.py (NewItemPage.__init__): Use it, instead
	of qm.test.base.standard_test_class_names.
	* share/dtml/test/new.dtml: Remove test class text field.
	* share/dtml/test/show.dtml: Only show explanatory text about
	properties when editing.
	
	* qm/fields.py (Field.GetDescription): Update docstring.
	(Field.GetBriefDescription): New method.
	* qm/structured_text.py (StructuredTextProcessor.__call__): Use
	get_paragraphs.
	(get_paragraphs): New function.
	(get_first_paragraph): Likewise.
	(__paragraph_regexp): New variable.
	* qm/test/web/show.py (ShowPage.GetBriefClassDescription): New
	method.
	* share/dtml/test/new.dtml: Correct typo.
	* share/dtml/test/show.dtml: Reduce verbosity; reoder some 
	comments.
	
	* qm/test/classes/command.py (ExecTest): Revise doc strings.
	(ShellCommandTest): Likewise.
	(ShellScriptTest): Likewise.
	* qm/test/classes/file.py (SubstitutionField): Likewise.
	(FileContentsTest): Likewise.
	* qm/test/classes/python.py (ExecTest): Likewise.
	(ExceptionTest): Likewise.
	(StringExceptionTest): Likewise.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>
	
	* qm/common.py (wrap_lines): Add indent parameter.
	* qm/test/cmdline.py (Command.summary_formats): New attribute.
	(Command.summary_option_spec): Remove.
	(Command.no_summary_option_spec): Likewise.
	(Command.conflicting_option_specs): Remove them.
	(Command.format_option_spec): New attribute.
	(Command.comamnds_spec): Add "summarize".  Adjust.
	(Command.Execute): Handle summarize.
	(Command.__ExecuteSummarize): New method.
	(Command.__ExecuteRun): Open results file later.  Adjust for
	__SummarizeResults.
	(Command.__WriteSummary): Remove.
	(Command.__SummarizeResults): New method.
	* qm/test/base.py (load_outcomes): Adjust for load_results.
	(read_results): Remove.
	(load_results): Return resource results too.
	(_results_from_dom): Remove.
	(_test_results_from_dom): New function.
	(_resource_results_from_dom): Likewise.
	(_result_from_dom): Adjust.
	(_count_outcomes): New function.
	(split_results_by_expected_outcomes): Likewise.
	(summarize_test_stats): Likewise.
	(summarize_relative_test_stats): Likewise.
	(summarize_test_suite_stats): Likewise.
	(summarize_results): Likewise.
	* share/diagnostics/test.txt (invalid results file): New
	diagnostic.
	(invalid results format): Likewise.
	(no results file specified): Likewise.
	(no such ID): Likewise.
	* tests/unit.qms/test.qms/suite3.qmt (suite_ids): Update.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/label.py (thunk): Call normpath on result.
	* qm/attachment.py (AttachmentStore): Add to doc string.
	(_temporary_location_prefix): Change.
	* qm/test/xmldb.py (AttachmentStore.Adopt): Fix doc string.
	(AttachmentStore.__MakeDataFilePath): Make safer file names.
	* qm/test/cmdline.py (Command.__WriteSummary): Bail early if no tests. 

2001-09-27  Mark Mitchell  <mark@codesourcery.com>

	* share/dtml/test/new-suite.dtml: Fix typo.

2001-09-26  Mark Mitchell  <mark@codesourcery.com>

	* qm/structured_text.py (TextFormatter.__style_markers): New
	variable.
	(TextFormatter.StartItem): Remove label parameter.
	(TextFormatter.StartStyle): Emit markers to indicate the style.
	(TextFormatter.EndStyle): Emit markers to indicate the style.
	(TextFormatter.FinishDefinedTerm): New
	function.
	(HtmlFormatter.__start_item_tags): Change definition list format.
	(HtmlFormatter.StartItem): Remove label parameter.
	(HtmlFormatter.FinishDefinedTerm): Likewise.
	(StructuredTextProcessor): Use __WriteText to format the label in
	a defined term.
	
	* configure.in (DOCBOOK_STYLESHEETS): Add another directory
	in which to locate xml.dcl.
	(--with-docbook-dtd): New option.
	* configure: Regenerated.
	* standard.mk.in (SGMLDIRS): Add @DOCBOOK_STYLESHEETS@.

2001-09-26  Alex Samuel  <samuel@codesourcery.com>

	* share/dtml/test/results.dtml: New file.
	* share/dtml/track/configuration-navigation-bar.dtml: Likewise.
	
2001-09-26  Alex Samuel  <samuel@codesourcery.com>

	* README: Update QMTRACK_DB_PATH name.
	* doc/manual/track-tour.xml: Explain configuration server.
	
	* qm/attachment.py: Rework entirely.
	* qm/xmlutil.py (load_xml_file): Add validate parameter.
	(load_xml): Likewise.
	(child_tag_predicate): New function.
	(get_child): Likewise.
	(get_children): Likewise.
	(get_child_text): Likewise.
	(get_child_texts): Likewise.
	(get_dom_child_text): Remove.
	(get_dom_children_texts): Likewise.
	* qm/web.py (HttpRedirect.__init__): New method.
	(WebRequestHandler.__HandleScriptRequest): Adjust accordingly.
	(WebServer.HandleNoSessionError): Likewise.
	(WebRequest.copy): Copy the client address.
	(handle_login): Adjust for change to HttpRedirect.
	(handle_logout): Likewise.
	(cache_page): Adjust for rmdir_recursively.
	(_handle_root): Adjust for change to HttpRedirect.
	* qm/user.py: Adjust for changes in xmlutil.
	* qm/label.py (root): New variable.
	(split): Rewrite.
	(split_fully): New function.
	(dirname): Use sep.
	* qm/fields.py: Adjust throughout for changes to xmlutil.
	(Field.class_name): New attribute.
	(Field.MakeDomNode): New method.
	(IntegerField.class_name): New attribute.
	(TextField.class_name): Likewise.
	(SetField.class_name): Likewise.
	(SetField.FormatValueAsHtml): Use attachment accessors.
	(SetField.MakeDomNode): New method.
	(UploadAttachmentPage.__init__): Use make_temporary_location.
	(UploadAttachmentPage.MakeSubmitUrl): Use upload_url.
	(AttachmentField.class_name): New attribute.
	(AttachmentField.upload_url): Likewise.
	(AttachmentField.download_url): Likewise.
	(AttachmentField.MakeDownloadUrl): Remove.
	(AttachmentField.FormatValueAsHtml): Use attachment accessors.
	(AttachmentField.FormEncodeValue): Likewise.
	(AttachmentField.FormDecodeValue): Don't use attachment_class.
	(AttachmentField.FormatSummary): Use attachment accessors.
	(AttachmentField.MakeDomNodeForValue): Use make_dom_node always.
	(EnumerationField.class_name): New attribute.
	(EnumerationField.__init__): Decode enumerals if necessary.
	(TimeField.class_name): New attribute.
	(UidField.class_name): New attribute.
	(from_dom_node): New function.
	* qm/common.py (Configuration): Remove.
	(remove_directory_recursively): Rename to...
	(rmdir_recursively): ... this.
	(load_module): Add default for path.
	(load_class): Likewise.
	(add_exit_function): Store external exit functions separately, and
	call them at the end.
	(make_map_from_list): New function.
	(purge_keys): Likewise.
	(make_unique_tag): Likewise.
	(_foreign_exit_functions): New variable.
	* qm/cmdline.py: Reformat comments.
	
	* qm/track/__init__.py: Remove imports.
	* qm/track/config.py: Remove.
	* qm/track/idb.py: Likewise.
	* qm/track/memory_idb.py: Likewise.
	* qm/track/issue_database.py: New file.
	* qm/track/issue_store.py: Likewise.
	* qm/track/memory_issue_store.py: Likewise.	
	* qm/track/qmtrack.in: Simplify, using run_command.
	* qm/track/issue_class.py (issue_classes_dtd): New constant.
	(IidField.class_name): New attribute.
	(StateField.class_name): Likewise.
	(StateField.__init__): Take state model from an attribute.
	(DiscussionField.class_name): New attribute.
	(DiscussionField.__init__): Take the contained field as a
	parameter. 
	(IssueClass.MakeDomNode): New method.
	(from_dom_node): New function.
	(load): Likewise.
	(save): Likewise.
	* qm/track/issue.py (ExpressionNameError): New exception class.
	(ExpressionSyntaxError): Likewise.
	(Attachment): Remove.
	(Issue.GetRevision): Rename to...
	(Issue.GetRevisionNumber): ... this.  Adjust accordingly
	throughout. 
	(get_issues_from_dom_node): Add issue_classes parameter.
	(get_issue_from_dom_node): Likewise.
	(get_histories_from_dom_node): Likewise.
	(get_history_from_dom_node): Likewise.
	(export_issues): Rename to...
	(write_issue_histories): ... this.  Adjust DOM format.
	(load_issue_histories): New function.
	(eval_issue_expression): Translate expression exceptions.
	(_initialize_module): Don't set qm.attachment.attachment_class. 
	* qm/track/cmdline.py: Adjust throughout for changes to IDB
	objects. 
	(idb_environment_variable_name): New constant. 
	(Command.idb_type_option_spec): Remove.
	(Command.issue_store_implementation_option_spec): New attribute.
	(Command.qmtrack_commands): Use it.  Add configure-idb.  Remove
	initialize.  
	(Command.__init__): Adjust dispatch accordingly.
	(Command.GetIdbPath): Use idb_environment_variable_name.
	(Command.RequiresIdb): Adjust for changes to commands.
	(Command.Execute): Add idb parameter.
	(Command.__PerformCreate): Likewise.
	(Command.__PerformEdit): Likewise.
	(Command.__PerformSplit): Likewise.
	(Command.__PerformJoin): Likewise.
	(Command.__PerformQuery): Likewise.
	(Command.__PerformConfigureIdb): New method.
	(Command.__PerformServer): Rewrite.
	(Command.__PerformShow): Add idb parameter.
	(Command.__PerformCreateIdb): Likewise.
	(Command.__PerformDestroyIdb): Likewise.  Don't lock here.
	(Command.__PerformImport): Likewise.
	(Command.__ImportIssueHistories): Likewise.
	(Command.__PrintResults): Likewise.  Build list of histories for
	export. 
	(run_command): New function.

	* qm/track/web/web.py (DefaultDtmlPage.navigation_bar_template):
	New attribute.
	(DefaultDtmlPage.GenerateStartBody): Use it.
	(DefaultDtmlPage.GetName): Use qm.common.program_name.
	(handle_download_attachment): Remove.
	(make_url_for_attachment): Remove.
	(_initialize_module): Don't set MakeDownloadUrl.
	* qm/track/web/summary.py: Get IDB from session and use issue
	store throughout.
	(handle_summary): Simplify query.  Handle query exceptions.
	* qm/track/web/show.py: Get IDB from session and use issue store
	throughout.
	(ShowPage.__init__): Don't get revisions here.  Initialize
	__history.
	(ShowPage.FormatFieldValue): Use GetHistory.
	(ShowPage.FormatHistory): Likewise.
	(ShowPage.GetHistory): New method.
	(retrieve_attachment_data): Remove.
	(handle_submit): Use _store_attachment_data.
	(_store_attachment_data): New function.
	* qm/track/web/query.py: Get IDB from session throughout.
	* qm/track/web/issue_class.py: Get IDB from session throughout.
	Adjust for HttpRedirect throughout.
	(handle_add_discussion): Construct TextField for DiscussionField. 
	* qm/track/web/index.py (IndexPage.__init__): 
	(IndexPage.__init__): Don't get issue classes.
	(IndexPage.GetIssueClasses): New method.
	(IndexPage.GetDefaultIssueClass): Likewise.
	* qm/track/server.py (_script_base): New constant.
	(WebServer): New class.
	(_make_server): New function.
	(make_server): Use it.
	(make_configuration_server): New function.
	(run_server): Remove.
	(execute): Likewise.
	(execute_locally): New function.
	(execute_remotely): Likewise.
	
	* share/xml/CATALOG: Add idb-configuration and issue-classes
	DTDs. 
	* share/xml/idb-configuration.dtd: New file.
	* share/xml/issue-classes.dtd: Likewise.
	* share/xml/fields.mod (mimetype): Rename to...
	(mime-type): ... this.
	* share/web/stylesheets/qm.css (tr.pass): New style.
	(tr.fail): Likewise.
	(tr.untested): Likewise.
	(tr.error): Likewise.
	(span.outcome): Likewise.
	(span.cause): Likewise.
	(span.id): Likewise.

	* qm/test/xmldb.py: Rework entirely.
	* qm/test/run.py: Adjust for changes in xmlutil throughout.
	(TestRun.Schedule): Improve diagnostics.
	* qm/test/cmdline.py (Command.Execute): Catch exception when
	loading database.
	(Command.MakeContext): Don't add path to context here.
	(Command.__ExecuteRun): Use expand_ids.
	(Command.__ExecuteServer): Pass database to make_server.
	* qm/test/base.py: Adjust for changes in xmlutil throughout.
	(Attachment): Remove.
	(InstanceBase.SetWorkingDirectory): Don't call
	__SetAttachmentPaths. 
	(InstanceBase.__MakeItem): Wrap attachments in arguments.
	(InstanceBase.__SetAttachmentPaths): Remove.
	(Suite): Reimplement.
	(Database.GetSuiteIds): Remove implicit parameter.
	(Database.GetAttachmentStore): New method.
	(Database.SetAttachmentData): Remove.
	(ResultWrapper.keys): New method.
	(get_suite_contents_recursively): New function.
	(expand_ids): Likewise.
	(load_database): Don't primt a message when the database module
	can't be imported.
	(run_test): Add path to context.
	Don't set qm.attachment.attachment_class.
	* qm/test/web/run.py: New file.
	* qm/test/web/web.py (DefaultDtmlPage.FormatTestId): Remove.
	(DefaultDtmlPage.FormatResourceId): Likewise.
	(DefaultDtmlPage.FormatSuiteId): Likewise.
	(DefaultDtmlPage.FormatId): New method.
	(make_server): Add database parameter.  Register attachment
	scripts. 
	* qm/test/web/suite.py: Adjust for changes in Suite.
	(handle_submit): Adjust for HttpRedirect.
	* qm/test/web/show.py (retrieve_attachment_data): Remove.
	(_retrieve_attachment_data): New function.
	(handle_submit): Adjust accordingly.  Adjust for HttpRedirect.
	(handle_delete): Likewise.
	* qm/test/web/dir.py (DirPage.FormatItem): Remove.
	* qm/test/classes/temporary.py (TempDirectoryResource.CleanUp):
	Adjust for rmdir_recursively.

	* share/dtml/track/show.dtml: Adjust for changes to Issue.
	* share/dtml/track/navigation-bar.dtml: Replace SC logo.
	* share/dtml/track/index.dtml: Use GetIssueClasses.  Remove Config
	IDB button.
	* share/dtml/track/history.dtml: Adjust for changes to Issue.
	* share/dtml/test/suite.dtml: Use FormatId.  Add Run button.
	Handle suites uniformly.
	* share/dtml/test/show.dtml: Use FormatId.  Add Run button.
	* share/dtml/test/navigation-bar.dtml: Replace SC logo.
	* share/dtml/test/dir.dtml: Adjust format.
	* share/dtml/exception.dtml: Escape type and value.

	* share/diagnostics/track.txt (idb directory missing): Adjust.
	(idb problem): Remove.
	(idb in use): New diagnostic.
	(idb path exists): Adjust.
	(initialize invalid idb class): Remove.
	(idb problem): New diagnostic.
	(idb server not accessible): Likewise.
	(issue store module error): Likewise.
	(new idb message): Adjust.
	(using local idb): New diagnostic.
	(using remote idb): Likewise.
	* share/diagnostics/test.txt (error loading xml resource): New
	diagnostic. 
	(error loading xml test): Adjust.
	(failed prerequisite): New diagnostic.
	(failed resource): Adjust.
	(incorrect prerequisite outcome): Remove.
	(no such action): Adjust
	(no such suite): New diagnostic.
	(no such test): Adjust.
	(no target for group): Likewise.
	* share/diagnostics/common.txt (invalid property): New
	diagnostic. 

	* tests/unit/common/format_time1.qmt: Remove.
	* tests/unit/common/graph_complete.qmt: Likewise.
	* tests/unit/common/graph_cycle.qmt: Likewise.
	* tests/unit/common/graph_pass.qmt: Likewise.
	* tests/unit/common/label_is_valid.qmt: Likewise.
	* tests/unit/common/label_thunk.qmt: Likewise.
	* tests/unit/common/parse_time1.qmt: Likewise.
	* tests/unit/common/parse_time2.qmt: Likewise.
	* tests/unit/common/parse_time3.qmt: Likewise.
	* tests/unit/common/parse_time4.qmt: Likewise.
	* tests/unit/common/parser_create.qmt: Likewise.
	* tests/unit/common/parser_dup_command_long.qmt: Likewise.
	* tests/unit/common/parser_dup_command_short.qmt: Likewise.
	* tests/unit/common/parser_duplicate_long.qmt: Likewise.
	* tests/unit/common/parser_duplicate_short.qmt: Likewise.
	* tests/unit/common/parser_help.qmt: Likewise.
	* tests/unit/common/parser_no_long.qmt: Likewise.
	* tests/unit/common/parser_parse.qmt: Likewise.
	* tests/unit/common/parser_two_char_short.qmt: Likewise.
	* tests/unit/test/classes/commandtest1.qmt: Likewise.
	* tests/unit/test/classes/scripttest1.qmt: Likewise.
	* tests/unit/test/classes/scripttest2.qmt: Likewise.
	* tests/unit/test/classes/scripttest3.qmt: Likewise.
	* tests/unit/test/classes/tempdir1.qma: Likewise.
	* tests/unit/test/classes/tempdir1.qmt: Likewise.
	* tests/unit/track/export/export1.qmt: Likewise.
	* tests/unit/track/export/export2.qmt: Likewise.
	* tests/unit/track/export/idb.qma: Likewise.
	* tests/unit/track/export/setup_idb.qmt: Likewise.
	* tests/unit.qms/common.qms/format_time1.qmt: New file.
	* tests/unit.qms/common.qms/graph_complete.qmt: Likewise.
	* tests/unit.qms/common.qms/graph_cycle.qmt: Likewise.
	* tests/unit.qms/common.qms/graph_pass.qmt: Likewise.
	* tests/unit.qms/common.qms/label_is_valid.qmt: Likewise.
	* tests/unit.qms/common.qms/label_thunk.qmt: Likewise.
	* tests/unit.qms/common.qms/parse_time1.qmt: Likewise.
	* tests/unit.qms/common.qms/parse_time2.qmt: Likewise.
	* tests/unit.qms/common.qms/parse_time3.qmt: Likewise.
	* tests/unit.qms/common.qms/parse_time4.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_create.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_dup_command_long.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_dup_command_short.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_duplicate_long.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_duplicate_short.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_help.qmt: Likewise.: Likewise.
	* tests/unit.qms/common.qms/parser_no_long.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_parse.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_two_char_short.qmt: Likewise.
	* tests/unit.qms/test.qms/suite1.qmt: Likewise.
	* tests/unit.qms/test.qms/suite2.qmt: Likewise.
	* tests/unit.qms/test.qms/suite3.qmt: Likewise.
	* tests/unit.qms/test.qms/test_suite1.qms: Likewise.
	* tests/unit.qms/test.qms/classes.qms/scripttest1.qmt: Likewise.
	* tests/unit.qms/test.qms/classes.qms/scripttest2.qmt: Likewise.
	* tests/unit.qms/test.qms/classes.qms/scripttest3.qmt: Likewise.
	* tests/unit.qms/test.qms/classes.qms/tempdir1.qma: Likewise.
	* tests/unit.qms/test.qms/classes.qms/tempdir1.qmt: Likewise.
	* tests/unit.qms/track.qms/export.qms/export1.qmt: Likewise.
	* tests/unit.qms/track.qms/export.qms/export2.qmt: Likewise.
	* tests/unit.qms/track.qms/export.qms/idb.qma: Likewise.
	* tests/unit.qms/track.qms/export.qms/setup_idb.qmt: Likewise.
	
2001-09-21  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_linux.py: Really remove it.

2001-09-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_linux.py: Rename to...
	* qm/platform_unix.py: ... this.
	(default_shell): New variable.
	(get_shell_for_command): New function.
	(get_shell_for_script): Likewise.
	* qm/platform.py: Adjust accordingly.
	* qm/common.py (split_argument_list): New function.
	* qm/test/classes/command.py (CommandTest): Rename too...
	(ShellCommandTest): ... this.
	(ShellCommandTest.fields): Remove interpreter field.
	(ShellCommandTest.__init__): Adjust accordingly.
	(ShellCommandTest.RunProgram): Likewise.
	(ScriptTest): Rename to...
	(ShellScriptTest): ... this.
	(ShellScriptTest.fields): Remove interpreter field.
	(ShellScriptTest.__init__): Adjust accordingly.
	(ShellScriptTest.RunProgram): Likewise.
	* qm/test/base.py (standard_test_class_names): Adjust accordingly.
	* doc/manual/common-manual.xml (sec-rc-common): Document
	command_shell and script_shell.xo
	* share/diagnostics/test.txt (no shell executable): New diagnostic.
	* tests/unit/test/classes/commandtest1.qmt: New test.
	* tests/unit/test/classes/scripttest1.qmt: Adjust.
	* tests/unit/test/classes/scripttest2.qmt: Likewise.
	* tests/unit/test/classes/scripttest3.qmt: Likewise.

2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install-sh: Restore, with corrected permissions.
	
2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install-sh: Remove.
	
2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install.py (copy_tree): Use makedirs.
	Warn on missing documentation files.

2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install.py (copy_tree): New function.
	Use it.
	* qm/test/classes/python.py (ExecTest.__init__): Make sure source
	is newline-terminated.

2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install.py: Substitute @python_version@ and @python_platform@.

2001-09-06  Alex Samuel  <samuel@codesourcery.com>

	* install.py: Exec setup_path.py.
	(packages): Build PyXML path.
	* doc/manual/test-tour.xml: Fix typos.

2001-09-05  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk.in (doc): Check for empty SUBDIRS.
	($(HTMLMANIFEST)): Likewise.
g
2001-09-05  Alex Samuel  <samuel@codesourcery.com>

	* qm/Makefile.in (setup_path.py): Use left-quotes.
	($(SCRIPTS):%): Likewise.
	* qm/platform.py: Use Linux module for Irix.
	* qm/test/cmdline.py (Command.context_file_spec): Rename long
	option to load-context.
	* share/web/stylesheets/qm.css (a.help-link): Adjust color.
	* doc/manual/test-manual.xml: Adjust accordingly.
	* doc/manual/test-reference.xml: Likewise.

2001-09-05  Alex Samuel  <samuel@codesourcery.com>

	* configure.in: Set up gadfly.
	* configure: Regenerate.
	* Makefile.in (setup): Remove rule.
	(gadfly/sqlwhere.py): Likewise.
	* standard.mk.in (.PHONY): Remove setup.
	(setup): Remove rule.
	* qm.spec (build): Don't make setup.
	* README: Adjust accordingly.

2001-09-04  Alex Samuel  <samuel@codesourcery.com>

	* configure.in: Extract PYTHON_VERSION, PYTHON_PREFIX,
	PYTHON_PLATFORM. 
	* configure: Regenerate.
	* standard.mk.in (PYTHON_VERSION): New variable.
	(PYTHON_PREFIX): Likewise.
	(PYTHON_PLATFORM): Likewise.
	(MAKEFILE_PRE_IN): Likewise.
	* Makefile.in (zope-dtml/ExtensionClass/Makefile): Remove rule.
	(sgmlop/Makefile): Use MAKEFILE_PRE_IN.
	* qm/Makefile.in (setup_path.py): Substitute @python_version@ and
	@python_platform@. 
	* qm/setup_path.py.in (get_python_version): New function.
	(__python_version): New variable.
	(__python_platform): Likewise.
	Use them for PyXML path.
	* qm/structured_text.py (__entity_char_regex): Handle
	single-character entities only.
	(__entity_char_replacement): Likewise.
	* zope-dtml/ExtensionClass/Makefile.in (TOPDIR): New variable.
	Include standard.mk.
	(all): Use PYTHON.
	* sgmlop/Makefile.in (TOPDIR): New variable.
	Include standard.mk.
	(all): Use PYTHON.
	
2001-09-04  Alex Samuel  <samuel@codesourcery.com>

	* configure.in: Rewrite.
	* configure: Regenerate.
	* standard.mk.in: Rewrite documentation portions.
	* qm/test/base.py (Database.HasTest): Implement here.
	(Database.HasSuite): Likewise.
	(Database.HasResource): Likewise.
	* qm/label.py (to_path): Comment.

2001-08-30  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Describe conventions for private names.
	* qm/setup_path.py.in (add_to_python_path): Adjust comment.
	* qm/test/cmdline.py (Command.__ExecuteServer): Adjust message.
	* share/dtml/track/index.dtml: Initialize style field.
	* share/diagnostics/common.txt (server url): New diagnostic.

2001-08-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (Database.GetTest): Handle ParseError.
	* qm/test/classes/command.py (ExecTest.fields): Change stdin,
	stdout, stderr fields to TextFields.
	(ExecTest.Run): Adjust accordingly.
	* tests/unit/test/classes/scripttest1.qmt: Likewise.
	* tests/unit/test/classes/scripttest2.qmt: Likewise.
	* tests/unit/test/classes/scripttest3.qmt: Likewise.
	* doc/manual/test-reference.xml: Likewise.

2001-08-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/classes/command.py (ScriptTest.fields): Make script
	field multiline.
	(ScriptTest.__init__): Test for empty string intepreter field.
	* tests/unit/test/classes/scripttest1.qmt: New test.
	* tests/unit/test/classes/scripttest2.qmt: Likewise.
	* tests/unit/test/classes/scripttest3.qmt: Likewise.
	* doc/manual/test-tour.xml: Fix typo.
	* doc/manual/test-reference.xml: Document some test classes. 

2001-08-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py (ContextWrapper.items): Fix.
	* qm/test/cmdline.py (Command.__init__): Reformat.
	* qm/test/web/show.py (retrieve_attachment_data): Only process
	temporary attachments.
	* qm/test/classes/command.py (ExecTest.MakeEnvironment): Add
	context variables to environment.

2001-08-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/setup_path.py.in (add_to_python_path): Prepend to path.

2001-08-22  Alex Samuel  <samuel@codesourcery.com>

	* qm.spec (files): Add qmtest-remote.

2001-08-22  Alex Samuel  <samuel@codesourcery.com>

	* install.py (scripts): Fix qmtest-remote script.

2001-08-22  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_win32.py (get_host_name): Fix syntax error.

2001-08-22  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (DirectorySuite.__ScanDirectory): Construct
	absolute test IDs.
	* qm/test/run.py (RemoteShellTarget.__init__): Use arguments
	property. 
	(TestRun.AddResourceResult): Immediately try to clean up after
	failed setup.
	* qm/test/cmdline.py (Command.commands_spec): Put ID in brackets.
	(Command.__ExecuteRun): Run all tests if none specified.  Collect
	explicit test suites.
	(Command.__WriteSummary): Print statistics by suite.  Supress null
	output. 
	* share/diagnostics/test.txt (no ids specified): Remove.
	* doc/qm.mod (PASS): New entity.
	(FAIL): Likewise.
	(ERROR): Likewise.
	(UNTESTED): Likewise.
	* doc/manual/test-manual.xml: Update and expand.
	* doc/manual/test-reference.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.

2001-08-19  Alex Samuel  <samuel@codesourcery.com>

	* install.py (scripts): Add qmtrack-remote.
	* qm.spec (files): Likewise.
	* qm/Makefile.in (SCRIPTS): Likewise.
	* qm/async.py (Channel.IsOpen): New method.
	(Multiplexer.Wait): Close channels if connection vanishes.
	(fork_with_stdio_channel): New function.
	* qm/test/run.py (Target.EnqueueRunTest): Implement here.
	(Target.EnqueueSetUpResource): Likewise.
	(Target.EnqueueCleanUpResource): Likewise.
	(Target.OnReplyReady): Likewise.
	(SubprocessTarget): Rename __children to _children and
	__ready_children to _ready_children.
	(SubprocessTarget.EnqueueSetUpResource): Likewise.
	(SubprocessTarget.EnqueueCleanUpResource): Likewise.
	(SubprocessTarget.OnReplyReady): Likewise.
	(SubprocessTarget.GetQueueLength): Subtract number of ready
	children. 
	(SubprocessTarget.OnReplyReady): Use base implementation.
	(SubprocessTarget.__EnqueueCommand): Rename to...
	(SubprocessTarget._EnqueueCommand): ... this.
	(RemoteShellTarget): New class.
	(_RemoteDemultiplexerTarget): Likewise.
	(test_run): Read multiple times from channels, if necessary.
	(_target_spec_from_dom): Fix duplicate variable name.
	* qm/test/qmtest-remote.in: New file.

2001-08-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (__host_name): Remove.
	(get_host_name): Likewise.
	(shuffle): New function.
	(sequence_difference): Likewise.
	* qm/async.py: New file.
	* qm/web.py (HTTPServer.server_bind): Use platform.get_host_name.
	* qm/platform_win32.py (get_host_name): New function.
	(_get_host_name): Likewise.
	* qm/platform_linux.py (run_program): Fix comment.
	(get_host_name): New function.

	* qm/track/cmdline.py (Command.__PerformServer): Use
	platform.get_host_name. 
	* qm/track/triggers/notification.py (_NotifyTrigger.__init__):
	Likewise. 

	* qm/test/run.py: New file.
	* qm/test/cmdline.py (Command.summary_option_spec): Remove
	short-form option. 
	(Command.profile_option_spec): Adjust.
	(Command.concurrent_option_spec): Likewise.
	(Command.remote_option_spec): Remove.
	(Command.targets_option_spec): New attribute.
	(Command.seed_option_spec): Likewise.
	(Command.commands_spec): Remove remote_option_spec.  Add
	targets_option_spec and seed_option_spec.  Sort.
	(Command.add_test_id): Adjust for new test run mechanism.
	(Command.__ExecuteServer): Use platform.get_host_name.
	(Command.__WriteSummary): Summarize resource results too.  Adjust
	output. 
	* qm/test/base.py (dtds): Add target DTD.
	(Resource.DoSetup): Rename to...
	(Resource.SetUp): ... this.
	(Resource.DoCleanup): Rename to...
	(Resource.CleanUp): ... this.
	(Resource.__Do): Use SetUp and CleanUp.
	(ResultWrapper.GetTestId): Rename to...
	(ResultWrapper.GetId): ... this.
	(ResultWrapper.MakeDomNode): Adjust accordingly.
	(ResultWrapper.__setitem__): New method.
	(ResultWrapper.__delitem__): Likewise.
	(PrerequisiteMapAdapter): Remove.
	(RemoteTestHost): Likewise.
	(Engine): Likewise.
	(InProcessEngine): Likewise.
	(ConcurrentyEngine): Likewise.
	(SubprocessEngine): Likewise.
	(MultiProcessEngine): Likewise.
	(MultiThreadEngine): Likewise.
	(CommandEngine): Likewise.
	(LocalCommandEngine): Likewise.
	(MultiRshEngine): Likewise.
	(RshEngine): Likewise.
	(write_results): Write resource results too.
	(read_results): Adjust for new DTD.
	(load_results): Likewise.
	(_results_from_dom): Likewise.
	(run_test): New function.
	(set_up_resource): Likewise.
	(clean_up_resource): Likewise.
	* qm/test/classes/temporary.py (TempDirectoryResource.DoSetup):
	Rename to...
	(TempDirectoryResource.SetUp): ... this.  Handle errors.
	(TempDirectoryResource.DoCleanup): Rename to...
	(TempDirectoryResource.CleanUp): ... this.  Handle errors.

	* share/xml/CATALOG: Add target DTD.
	* share/xml/result.dtd: Adjust to include resource results.
	(results): Rename to...
	(test-run): ... this.
	(test-results): New element.
	(resource-results): Likewise.
	* share/xml/target.dtd: New file.
	* share/diagnostics/test.txt (concurrency not integer): New
	diagnostic. 
	(failed resource): Likewise.
	(incorrect prerequisite outcome): Likewise.
	(no target for group): Likewise.
	(seed not integer): Likewise.
	* tests/unit/common/parser_create.qmt: Adjust.
	* tests/unit/common/parser_parse.qmt: Likewise.
	* tests/unit/common/parser_help.qmt: Likewise.
	* tests/unit/test/classes/tempdir1.qmt: Likewise.
	
2001-07-20  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (Database.__ParseResourceDocument): Fix wrong
	variabel name.

2001-07-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py: Rename "action" to "resource" throughout.
	(InstanceBase.__init__): Add properties parameter
	(InstanceBase.SetProperty): New method.
	(InstanceBase.GetProperty): Likewise.
	(InstanceBase.GetProperties): Likewise.
	(Test.__init__): Add properties parameter.
	(Test.GetPrerequisites): Remove absolute parameter.
	(Test.GetResources): Likewise.
	(Resource.__init__): Add properties parameter.
	(Suite.GetTestIds): Assume absolute IDs.
	(Suite.GetRawTestIds): Likewise.
	(Suite.GetRawSuiteIds): Likewise.
	(PrerequisiteMapAdapter.__getitem__): Remove absolute argument.
	(PrerequisiteMapAdapter.get): Likewise.
	* qm/test/xmldb.py: Rename "action" to "resource" throughout.
	(Database.WriteSuite): Assume absolute IDs.
	(Database.__ParseTestDocument): Load properties.
	(Database.__ParseResourceDocument): Likewise.
	(Database.__GetPropertiesFromDomNode): New method.
	(Database.__MakeDomNodeForItem): Include properties.
	* qm/test/cmdline.py (Command.unexpected_sorter): Rename "action"
	to "resource".
	* qm/test/web/web.py: Rename "action" to "resource" throughout.
	(DefaultDtmlPage.FormatTestId): Remove relative_to and within
	parameters. 
	(DefaultDtmlPage.FormatResourceId): Likwise.
	(DefaultDtmlPage.FormatSuiteId): Remove within parameter.
	* qm/test/web/dir.py: Rename "action" to "resource" throughout.
	* qm/test/web/show.py: Likewise.
	(handle_submit): Handle properties.
	* qm/test/web/suite.py (ShowPage.FormatSuiteId): Remove.
	* qm/test/classes/temporary.py: Rename "action" to "resource"
	throughout.
	* share/diagnostics/test-help.txt: Likewise.
	* share/dtml/test/dir.dtml: Likewise.
	* share/dtml/test/suite.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.  Show properties.  Adjust
	formatting. 
	* share/xml/test.dtd: Rename "action" to "resource" throughout.
	* share/xml/CATALOG: Likewise.
	* share/xml/action.dtd: Remove.
	* share/xml/resource.dtd: New file.
	* share/web/common.js (property_add_or_change): Check if name is
	valid. 
	* share/web/dtml/test/add-action.dtml: Remove.
	* share/web/dtml/test/add-resource.dtml: New file.
	* unit/common/parser_help.qmt: Make IDs absolute.
	* unit/common/parser_parse.qmt: Likewise.
	* unit/test/classes/tempdir1.qma: Likewise.
	* unit/test/classes/tempdir1.qmt: Likewise.
	* unit/track/export/export1.qmt: Likewise.
	* unit/track/export/export2.qmt: Likewise.
	* unit/track/export/idb.qma: Likewise.
	* unit/track/export/setup_idb.qmt: Likewise.

2001-07-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/config.py (setup_idb_for_internal_use): Make
	description field multiline.
	(setup_idb_for_test): Likewise.

2001-07-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/config.py (open_idb): Fix IDB check.  Improve
	diagnostics.
	* share/diagnostics/track.txt (idb directory missing): New
	diagnostic. 
	(idb problem): Likewise.
	(idb path inaccessible): Likewise.
	(idb path wrong): Likewise.
	* share/dtml/track/summary-color-key.dtml: Adjust formatting.

2001-07-16  Alex Samuel  <samuel@codesourcery.com>

	* README: No longer require PyXML.

2001-07-16  Alex Samuel  <samuel@codesourcery.com>

	* PyXML: New imported module.
	* install.py (packages): Include PyXML dir.
	* Makefile.in (SUBDIRS): Add PyXML.
	(PyXML): New rule.
	* qm/setup_path.py.in: Add PyXML dir to Python path.

	* qm/web.py (escape): Rename second definition to...
	(javascript_escape): ... this.
	(unescape): Rename second definition to...
	(javascript_unescape): ... this.
	* qm/track/issue_class.py (encode_state): Use javascript_escape.
	(encode_transition): Likewise.
	(decode_state): Use javascript_unescape.
	(decode_transition): Likewise.
	* qm/test/classes/python.py (ExecTest.fields): Make text fields
	multiline. 
	(BaseExceptionTest.fields): Likewise.
	(BaseExceptionTest.CheckArgument): Improve diagnostic.
	(ExceptionTest.CheckArgument): Likewise.
	* qm/test/classes/file.py (FileContentsField.fields): Make text
	field multiline.
	* share/diagnostics/test.txt (test raised wrong argument): Reword.
	
2001-07-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (DtmlPage.__init__): Remove show_decorations parameter.
	(DtmlPage.GenerateStartBody): Add decorations parameter.
	(DtmlPage.GenerateEndBody): Likewise.
	(DtmlPage.MakeSubmitButton): Remove.
	(DtmlPage.MakeButton): Add css_class parameter.
	(format_exception): Use DtmlPage.default_class.
	(make_button_for_request): Add css_class parameter.
	(make_button_for_url): Likewise.
	(generate_error_page): Use DtmlPage.default_class.
	(generate_login_form): Likewise.
	(make_submit_button): New function.
	* qm/track/web/web.py (DtmlPage): Split off...
	(DefaultDtmlPage): ... this base class.
	(DefaultDtmlPage.GenerateStartBody): Add decorations parameter.
	(_initialize_module): Use DefaultDtmlPage as default_class.
	* qm/track/web/summary.py (DisplayOptionsPage.__init__): Remove
	show_decorations argument.
	(ColorKeyPage.__init__): Likewise.
	* qm/track/issue_class.py (StateField.MakePropertyControls):
	Adjust popup size.
	* qm/test/web/web.py (DtmlPage): Split off...
	(DefaultDtmlPage): ... this base class.
	(__initialize_module): Use DefaultDtmlPage as default_class.
	* qm/test/web/show.py (ShowPage.MakeCategoriesControl): Remove
	show_decorations argument.
	(AddPrerequisitePage.__init__): Likewise.
	(AddActionPage.__init__): Likewise.
	* share/web/stylesheets/qm.css (tr.form-submit): New class.
	(input.submit): Likewise.
	* share/dtml/field.dtml: Adjust formatting.
	* share/dtml/problems.dtml: Likewise.
	* share/dtml/track/summary-display-options.dtml: Likewise.
	* share/dtml/track/summary-color-key.dtml: Likewise.
	* share/dtml/track/show.dtml: Likewise.
	* share/dtml/track/issue-class.dtml: Likewise.
	* share/dtml/test/suite.dtml: Likewise.
	* share/dtml/test/add-prerequisite.dtml: Likewise.
	* share/dtml/test/add-category.dtml: Likewise.
	* share/dtml/test/add-action.dtml: Likewise.
	* share/dtml/user.dtml: Likewise.
	* share/dtml/track/state-model.dtml: Likewise.  Add help link.
	* share/diagnostics/track-help.txt (state model help): New help
	page.

2001-07-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (escape): New function.
	(unescape): Likewise.
	* qm/fields.py (Field.UpdateFromRequest): Remove debugging output.
	(EnumerationField.__init__): Handle 'None' default.
	(EnumerationField.CompareValues): Handle values not among
	enumerals. 
	(EnumerationField.SetAttribute): Don't muck with the default value.
	* qm/track/server.py (make_server): Register state-model.
	* qm/track/qmtrack.in: Handle all other exceptions.
	* qm/track/issue_class.py (Transition.__init__): Make condition
	parameter not a list.
	(Transition.GetConditions): Rename to...
	(Transition.GetCondition): ... this.
	(StateField.property_declarations): New attribute.
	(StateField.__init__): Don't stort state model as object
	attribute.  Call SetStateModel.
	(StateField.SetStateModel): New method.
	(StateField.GetStateModel): Use field attribute.
	(StateField.GetEnumerals): Use GetStateModel.
	(StateField.FormatValueAsHtml): Handle value not among enumerals.
	(StateField.MakePropertyControls): New method.
	(encode_state_model): New function
	(encode_state): Likewise.
	(encode_transition): Likewise.
	(decode_state_model): Likewise.
	(decode_state): Likewise.
	(decode_transition): Likewise.
	(_initialize_module): Reformat descriptions.
	* qm/track/config.py (__global_lock): Rename to...
	(_global_lock): ... this.
	Adjust accordingly throughout.
	(open_idb): Improve diagnostic.
	* qm/track/web/issue_class.py (handle_state_model): New.
	* qm/track/triggers/state.py (Trigger.Preupdate): Handle old state
	not in state model.  Adjust for single condition.
	* share/web/common.js (popup_box): New function.
	(label_is_valid): Likewise.
	(select_item): Likewise.
	(get_selected_value): Likewise.
	* share/dtml/track/state-model.dtml: New template.

2001-07-14  Alex Samuel  <samuel@codesourcery.com>

	* share/dtml/attachment.dtml: Use file name if description not
	specified. 

2001-07-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.GetHtmlHelp): Don't print field name in
	smaller font.
	* qm/structured_text.py (TextFormatter.__init__): Add attributes.
	(TextFormatter.End): New method.
	(TextFormatter.StartLink): Implement.
	(TextFormatter.EndLink): Likewise.
	(HtmlFormatter.End): New method.
	(StructuredTextProcessor.__punctuation): Reformat.
	(StructuredTextProcessor.__verbatim_regex): Accept line-end
	terminator. 
	(StructuredTextProcessor.__strong_regex): Likewise.
	(StructuredTextProcessor.__emph_regex): Likewise.
	(StructuredTextProcessor.__underline_regex): Likewise.
	(StructuredTextProcessor.__link1_regex): Remove.
	(StructuredTextProcessor.__link2_regex): Likewise.
	(StructuredTextProcessor.__link_regex): New attribute.
	(StructuredTextProcessor.__link_footnote_regex): Likewise.
	(StructuredTextProcessor.__init__): Add attribute.
	(StructuredTextProcessor.__call__): Process hyperlink footnotes. 
	(StructuredTextProcessor.End): Call formatter's End method.
	(StructuredTextProcessor.__WriteText): Rewrite hyperlink
	processing. 
	* qm/track/web/summary.py (SummaryPage.__init__): Build dictionary
	map.
	(SummaryPage.MakeDisplayOptionsButton): Pass field dictionary to
	DisplayOptionsPage. 
	(SummaryPage.MakeColorKeyButton): Pass fields to ColorKeyPage.
	(DisplayOptionsPage.__init__): Take field dictionary parameter.  
	(DisplayOptionsPage.GetTitle): Handle IndexError.
	(ColorKeyPage.__init__): Take field parameters.
	(_hls_transform): Improve doc string.
	* share/dtml/track/summary.dtml: Adjust formatting.

2001-07-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/index.py (handle_index): Make a function.

2001-07-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (FieldEditPage.MakeDefaultValueControl): New method.
	(Field.UpdateFromRequest): Process default value.
	(TextField.FormatValueAsHtml): Don't escape structured text HTML.
	(EnumerationField.FormatValueAsHtml): Don't use
	_GetAvailableEnumerals. 
	(EnumerationField._GetAvailableEnumerals): Remove.
	* qm/track/issue_class.py (StateField.FormatValueAsHtml): New
	method.
	(IssueClass.__init__): Make some more mandatory fields read-only.
	* share/web/stylesheets/qm.css (th): Make background black.
	(a#colhead): Likewise.
	* share/dtml/field.dtml: Add control for default value.

2001-07-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/structured_text.py (TextFormatter.WriteText): Don't print
	spaces at the start of a line.
	* qm/common.py (MutexError): New exception.
	(MutexLockError): Update doc string.
	(FileSystemMutex.Lock): Raise MutexError.
	* qm/cmdline.py: Rename "flag" to "option" throughout.
	* qm/track/server.py (execute): Don't handle CommandError here.
	* qm/track/qmtrack.in: Use GetIdbPath.  Improve diagnostics.
	* qm/track/config.py (initialize_idb): Improve diagnostics.
	* qm/track/cmdline.py (Command.force_option_spec): New attribute.
	(Command.qmtrack_commands): Use it.  Change flags for initialize
	and destroy.
	(Command.__init__): Fix dispatch map.
	(Command.GetIdbPath): New method.
	(Command.Execute): Don't check for missing command here.
	(Command.__Parse): Do it here instead.
	(Command.__PerformInitialize): Use GetIdbPath.
	(Command.__PerformDestroy): Likewise.
	* share/diagnostics/common.txt (invalid enum value): New
	diagnostic. 
	(missing command): Rewrite.
	(unrecognized command): New diagnostic.
	* share/diagnostics/track.txt (create field error): Fix
	substitution. 
	(create issue error): Likewise.
	(create no equals): Likewise.
	(edit issue error sem): Likewise.
	(field exist): Likewise.
	(field set use equal): Likewise.
	(field set use plus): Likewise.
	(idb locked): Likewise.  Adjust wording.
	(idb parent directory inaccessible): New diagnostic.
	(idb parent directory missing): Likewise.
	(idb path exists): Likewise.
	(initialize no idb path): Remove.
	(initialize wrong flag): Likewise.
	(invalid enum value): Likewise.
	(join iid error sem): Fix substitution.
	(join issue error sem): Likewise.
	(join issue error syn): Likewise.
	(no idb at path): New diagnostic.
	(show no iid): Fix substitution.
	(show wrong args): Likewise.
	(split issue error sem): Likewise.
	* doc/manual/track-tour.xml: Update for changes in initialize
	syntax. 

2001-07-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (TextField.property_declarations): Rename nonempty
	to not_empty_text. 
	(TextField.CompareValues): Re-compare strings case-sensitively. 
	(TextField.Validate): Adjust for not_empty_text.  
	(TextField.GetHelp): Likewise.
	(SetField.set_property_declarations): New attribute.
	(SetField.__init__): Use it.
	(SetField.CompareValues): Recompare set contents if they're the
	same length. 
	(SetField.Validate): Check not_empty_set attribute.
	* qm/track/issue_class.py (IssueClass.__init__): Use
	not_empty_text. 
	* qm/track/web/web.py (HistoryPageFragment.FormatRevisionDiff):
	Use field titles in output.
	* share/diagnostics/common.txt (empty set field value): New
	diagnostic.
	(empty text field value): Likewise.
	* share/diagnostics/track.txt (empty field value): Remove.

2001-07-12  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.ValuesAreEqual): Rename to...
	(Field.CompareValues): ... this.
	(TextField.CompareValues): New method.
	(TextField.FormatValueAsHtml): Truncate to 80 characters.
	(SetField.CompareValues): New method.
	(EnumerationField.CompareValues): Likewise.
	* qm/web.py (format_color): New function.
	* qm/track/issue.py (IssueSortPredicate.__init__): Take field as
	parameter. 
	(IssueSortPredicate.__call__): Use CompareValues.
	(get_differing_fields): Likewise.
	(difference_issues): Likewise.
	* qm/track/web/summary.py (SummaryPage.__init__): Add
	hue_field_name, lightness_field_name, saturation_field_name
	parameters.  Pass field to IssueSortPredicate.
	(SummaryPage.MakeDisplayOptionsButton): Pass coloring fields to
	display options page.
	(SummaryPage.IsIssueShown): Remove.
	(SummaryPage.MakeColorKeyButton): New method.
	(SummaryPage.GetBackgroundColor): Reimplement.
	(SummaryPage.GetForegroundColor): Remove.
	(SummaryPage.MakeIssueUrl): Likewise.
	(DisplayOptionsPage.__init__): Add hue_field_name,
	lightness_field_name, saturation_field_name parameters.
	(DisplayOptionsPage.MakeColorableFieldSelect): New method.
	(ColorKeyPage): New class.
	(handle_summary): Set up issue coloring.
	(_color_value_for_enum_field): New function.
	(_color_value_for_enum): Likewise.
	(_hls_transform): Likewise.
	* share/dtml/track/summary.dtml: Add color key button.  Don't use
	IsIssueShown, MakeIssueUrl, GetForegroundColor.
	* share/dtml/track/summary-display-options.dtml: Add heading and
	help link.  Add controls for coloring.
	* share/dtml/track/summary-color-key.dtml: New file.
	* share/diagnostics/track-help.txt (summary display options help):
	New help message.
	
2001-07-11  Alex Samuel  <samuel@codesourcery.com>

	* COPYING: Update year.

	* qm/web.py (WebRequestHandler.do_POST): Improve error handling.
	(format_exception): Don't use default_class.
	(generate_login_form): Likewise.
	(make_set_control): Add ordered parameter.
	(make_choose_control): Adjust for encode_select_options.
	(format_user_id): DOn't use default_class.
	* qm/user.py (XmlDatabase.__init__): Improve exception.
	* qm/platform_linux.py (open_in_browser): Improve error handling. 
	* qm/fields.py (Field.property_declarations): Fix swapped
	attribute descriptions.
	(TextField.property_declarations): Add multiline attribute.
	(TextField.Validate): Remove line breaks if not multiline.
	(TextField.FormatValueAsHtml): Reorganize for multiline.
	(TextField.MakePropertyControls): Add control for multiline.
	(EnumerationField.property_declarations): Augment description.
	(EnumerationField.MakePropertyControls): Make ordered set
	control. 
	(TimeField.FormatValueAsHtml): Improve full output format.
	* qm/common.py (add_exit_function): Handle foreign exit function
	better. 
	(print_message): Allow zero min_verbose.
	* qm/track/qmtrack.in: Use qm.track.server module.
	* qm/track/server.py (start_server): Rename to...
	(make_server): ... this.  Don't start serving.
	(run_server): New function.
	* qm/track/issue_class.py (StateField.UpdateEnumeration): Remove.
	(StateField.GetEnumerals): New method.
	(StateField.GetHelp): Put state names in italics.
	* qm/track/cmdline.py (Command.start_browser_option_spec): New
	attribute.
	(Command.qmtrack_commands): Include it.  Don't list GadflyIdb.
	(Command.__PerformServer): Print a message if port number isn't
	specified.  Handle --start-browser option.
	* qm/test/cmdline.py (Command.__ExecuteServer): Improve message.
	
	* share/web/common.js: Comment throughout.
	(remove_from_set): Adjust for encode_select_options.
	(add_to_set): Likewise.
	(move_in_set): New function.
	(update_from_select_list): Replace with...
	(encode_select_options): ... this.
	(property_add_or_change): Adjust for encode_select_options.
	(property_remove): Likewise.
	* share/dtml/field.dtml: Adjust layout.
	* share/dtml/track/show.dtml: Fix Cancel button.
	* share/dtml/track/issue-class.dtml: Don't list triggers.
	* share/dtml/track/add-issue-class.dtml: Improve help text.
	* share/diagnostics/track.txt (initialize invalid idb class): Fix.

	* doc/manual/track-tour.xml (sec-tractut-user-db): Document
	--start-browser option. 
	* doc/manual/test-manual.xml (sec-database-contents): New section. 

2001-07-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo): Rename to...
	(DtmlPage): ... this.
	(DtmlPage.html_header): Remove.
	(DtmlPage.html_footer): Likewise.
	(DtmlPage.table_attributes): Likewise.
	(DtmlPage.__init__): Remove request parameter.
	(DtmlPage.__call__): New method.
	(DtmlPage.FormatStructuredText): Remove.
	(DtmlPage.MakeUrl): Likewise.
	(DtmlPage.WebRequest): New method.
	(DtmlPage.GenerateHtmlHeader): Put application name in title.
	(DtmlPage.GenerateEndBody): Conditionalize "problems" message.
	(DtmlPage.MakeSubmitButton): New method.
	(DtmlPage.MakeUrlButton): Remove.
	(DtmlPage.MakeHelpLink): Likewise.
	(DtmlPage.MakeHelpLinkHtml): Likewise.
	(format_exception): Use DtmlPage.
	(generate_html_from_dtml): Remove.
	(generate_error_page): Use DtmlPage.
	(generate_login_form): Likewise.
	(make_help_link): Add default for label parameter.
	(make_help_link_html): Likewise.  Use DtmlPage.
	(make_choose_control): Adjust button spacing.
	(_handle_problems): Convert to DtmlPage object.
	(format_user_id): Use DtmlPage.
	* qm/fields.py: Adjust throughout for DtmlPage.

	* qm/track/web/web.py (PageInfo): Rename to...
	(DtmlPage): ... this, and convert. 
	Adjust accordingly throughout.
	(DtmlPage.GenerateStartBody): Use document template.
	(generate_html_from_dtml): Remove.
	* qm/track/web/index.py: Adjust throughout for DtmlPage.
	* qm/track/web/issue_class.py: Likewise.
	* qm/track/web/query.py: Likewise.
	* qm/track/web/show.py: Likewise.
	* qm/track/web/summary.py: Likewise.
	
	* qm/test/web/web.py (PageInfo): Rename to...
	(DtmlPage): ... this, and convert.
	(generate_html_from_dtml): Remove.
	* qm/test/web/dir.py: Adjust throughout for DtmlPage.
	* qm/test/web/show.py: Likewise.
	* qm/test/web/suite.py: Likewise.
	
	* share/dtml/attachment.dtml: Adjust for DtmlPage.
	* share/dtml/set.dtml: Likewise.
	* share/dtml/test/add-action.dtml: Likewise.
	* share/dtml/test/add-category.dtml: Likewise.
	* share/dtml/test/add-prerequisite.dtml: Likewise.
	* share/dtml/test/new-suite.dtml: Likewise.
	* share/dtml/test/new.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/dtml/test/suite.dtml: Likewise.
	* share/dtml/test/navigation-bar.dtml: New file.
	* share/dtml/track/add-issue-class.dtml: Adjust for DtmlPage.
	* share/dtml/track/add-issue-field.dtml: Likewise.
	* share/dtml/track/config-idb.dtml: Likewise.
	* share/dtml/track/history.dtml: Likewise.
	* share/dtml/track/index.dtml: Likewise.
	* share/dtml/track/issue-class.dtml: Likewise.
	* share/dtml/track/notification.dtml: Likewise.
	* share/dtml/track/query.dtml: Likewise.
	* share/dtml/track/show.dtml: Likewise.
	* share/dtml/track/subscription.dtml: Likewise.
	* share/dtml/track/summary-display-options.dtml: Likewise.
	* share/dtml/track/summary.dtml: Likewise.

2001-07-04  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (iid): New entity.
	* doc/manual/track-tour.xml: Add "Adding Fields", "Special
	Features" sections.

2001-07-04  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.qm_bug_system_url): Update.
	* share/dtml/track/navigation-bar.dtml: Adjust URLs.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/show.py (handle_submit): Handle IssueExistsError. 
	* share/dtml/track/summary.dtml: Top-align issue rows.
	* share/diagnostics/track.txt (iid already used): New diagnostic.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (SetField.__init__): Use contained field property
	declarations. 
	(SetField.MakePropertyControls): New method.
	(EnumerationField.property_declarations): New
	attribute. 
	(EnumerationField.__init__): Change enumeration parameter to
	enumerals. 
	(EnumerationField.SetAttribute): New method.
	(EnumerationField.SetEnumerals): Simplify.
	(EnumerationField.GetEnumerals): Handle empty enumerals.
	(EnumerationField.MakePropertyControls): New method.
	* qm/track/issue_class.py (StateField.__init__): Adjust base class
	initializer call.
	* qm/track/config.py (setup_idb_for_internal_use): Adjust priority
	enumerals.
	(setup_idb_for_test): Adjust severity enumerals.
	* qm/track/web/issue_class.py (_get_issue_class_for_session):
	Don't check issue object ID.
	(handle_show_class): Don't set issue object ID in request.
	(handle_submit_field): Redirect after processing field.
	(handle_delete_field): Don't copy request.
	(handle_new_field): Likewise.
	(handle_new_class): Likewise.
	(handle_submit_notification): Likewise.
	(handle_submit_subscription): Likewise.
	(handle_add_discussion): Likewise.
	* share/dtml/track/issue-class.dtml: Don't open edit page in new
	browser window.
	* share/dtml/add-enumeral.dtml: New template.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (Enumeral): Remove.
	* qm/fields.py (EnumerationField): Reimplement as TextField subclass.
	* qm/track/issue_class.py (StateField.__init__): Adjust accordingly.
	(StateField.UpdateEnumeration): Likewise.
	(StateField._EnumerationField__GetAvailableEnumerals): Rename to...
	(StateField._GetAvailableEnumerals): ... this.
	* qm/track/web/query.py (QueryPageInfo.MakeCategorySelect): Adjust
	accordingly.
	(QueryPageInfo.MakeStateSelect): Likewise.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (idb): New entity.
	* doc/manual/manual.xml (track-tour.xml): New entity.
	Use it.
	* doc/manual/track-tour.xml: New file.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/issue_class.py (NotificationPageInfo): New class.
	(handle_show_notification): New function.
	(handle_submit_notification): Likewise.
	(handle_show_subscription): Likewise.
	(handle_submit_subscription): Likewise.
	(handle_add_discussion): Likewise.
	* qm/track/triggers/notification.py (NotifyFixedTrigger.__init__):
	Separate recpients by email address and UID.
	(NotifyFixedTrigger.GetSubscriberAddresses): Reimplement.
	(NotifyFixedTrigger.GetRecipientAddresses): New method.
	(NotifyFixedTrigger.GetRecipientUids): Likewise.
	(NotifyFixedTrigger.AddSubscriberAddress): Rename to...
	(NotifyFixedTrigger.AddRecipientAddress): ... this.
	(NotifyFixedTrigger.AddSubscriberUid): Rename to...
	(NotifyFixedTrigger.AddRecipientUid): ... this.
	* qm/track/server.py (start_server): Register add-discussion,
	show-notification, show-subscription, submit-notification,
	submit-subscription. 
	* qm/track/issue_class.py (IssueClass.__init__): Adjust descriptions.
	(IssueClass.RegisterTrigger): Remove existing trigger.
	(IssueClass.GetTrigger): New method.

	* share/dtml/track/issue-class.dtml: Add buttons for special
	features. 
	* share/dtml/track/add-notification-address.dtml: New template.
	* share/dtml/track/add-notification-uid.dtml: Likewise.
	* share/dtml/track/subscription.dtml: Likewise.
	* share/dtml/track/notification.dtml: Likewise.
	* share/dtml/track/add-issue-class.dtml: Clean up.

2001-07-02  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_set_control): Add ellipsis to Add...
	(make_select): Add update_external_field parameter.
	* qm/track/web/query.py (QueryPageInfo.MakePythonQueryHelp):
	Handle no issue classes case.
	(QueryPageInfo.MakeCategorySelect): Likewise.
	(QueryPageInfo.MakeStateSelect): Likewise.
	* qm/track/web/issue_class.py (AddClassPageInfo): New class.
	(handle_add_class): New function.
	(handle_new_class): Likewise.
	* qm/track/web/index.py (IndexPageInfo.__init__): Don't set
	default_issue_class if there are none.
	* qm/track/server.py (start_server): Register add-issue-class,
	new-issue-class. 
	* qm/track/issue_class.py (default_categories): Make it a list.
	(IssueClass.__init__): Convert categories from list to map.
	* qm/track/config.py (setup_idb_for_internal_use): Make categories
	a list.
	* share/diagnostics/track.txt (invalid class name): New
	diagnostic.
	(missing class title): Likewise.
	* share/dtml/track/issue-class.dtml: Use issue class title.
	Adjust. 
	* share/dtml/track/index.dtml: Handle no issue class case.
	* share/dtml/track/config-idb.dtml: Adjust formatting.  Add button
	to add a new class.
	* share/dtml/track/add-issue-class.dtml: Likewise.
	* share/dtml/track/add-category-name.dtml: New template.

2001-07-02  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeLoginForm): Add default_user_id
	parameter. 
	(generate_login_form): Set default_user_id attribute.
	* qm/track/server.py (do_command_for_xml_rpc): Fix typos.
	* qm/track/qmtrack.in: Handle remote-idb option.
	* qm/track/config.py (set_remote_mode): New function.
	(open_idb): Use it.
	* qm/track/cmdline.py (Command.database_option_spec): Change short
	form to D.
	(Command.remote_database_option_spec): New attribute.
	(Command.qmtrack_option_specs): Include it.
	* qm/test/classes/file.py (FileContentsTest.__init__): Remove
	debugging output.
	* share/dtml/login_form.dtml: Use default_user_id in login form.

2001-07-01  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/server.py (start_server): Move imports of qm.track.web
	modules here.  Register add-issue-field, delete-issue-field,
	new-issue-field.
	* qm/track/memory_idb.py (MemoryIdb.__init__): Add sanity checks.
	(MemoryIdb.UpdateIssueClass): Rewrite field handling code.  Update
	issues. 
	* qm/track/issue_class.py (mandatory_field_names): New constant.
	(IssueClass.RemoveField): New method.
	* qm/track/web/summary.py (SummaryPageInfo.FormatFieldValue):
	Watch for missing fields.
	* qm/track/web/issue_class.py (ShowPageInfo.madatory_field_names):
	New attribute.
	(NewFieldPageInfo): New class.
	(handle_delete_field): New function.
	(handle_add_field): Likewise.
	(handle_new_field): Likewise.
	* share/dtml/track/issue-class.dtml: Use MakeButton.  Activate
	buttons.
	* share/dtml/track/add-issue-field.dtml: New template.
	* share/diagnostics/track.txt (invalid field type): New
	diagnostic. 

2001-06-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/idb.py: Remove obsolete imports.

2001-06-26  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_set_control): Escape text.
	* qm/fields.py (TextField.FormatValueAsHtml): Adjust verbatim output.
	(SetField.FormatValueAsHtml): Use FormatValueAsText for contents.
	* qm/track/memory_idb.py (MemoryIdb.AddRevision): Fix typo.
	* qm/test/web/suite.py (ShowPageInfo.FormatSuiteId): New method.
	* qm/test/classes/file.py: New file.
	* qm/test/classes/command.py (ScriptTest.fields): Make script
	field a text field. 
	(ScriptTest.__init__): Adjust correspondingly.
	* qm/test/cmdline.py (Command.__ExecuteServer): Use print_message.
	* qm/test/base.py (standard_test_class_names): Add
	file.FileContentsTest.
	* share/dtml/test/suite.dtml: Use FormatSuiteId.
	* share/diagnostics/test.txt (file invalid pattern): New
	diagnostic.
	(file invalid substitution): Likewise.
	* tests/unit/track/export/idb.qma: New action.
	* tests/unit/track/export/export1.qmt: New test.
	* tests/unit/track/export/export2.qmt: Likewise.
	* tests/unit/track/export/setup_idb.qmt: Likewise.

2001-06-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (decode_properties): Handle empty properties.
	(format_user_id): Use red instead of blink.
	* qm/fields.py (Field.SetDefaultValue): Don't validate.
	(EnumerationField.Validate): Fix lambda.

	* qm/track/sql_idb.py: Adjust method names throughout.
	* qm/track/memory_idb.py: Likewise.
	(MemoryIdb.AddIssue): Add insert parameter.  Do't use
	__InsertIssue.
	(MemoryIdb.AddRevision): Likewise.
	(MemoryIdb.HasIssue): New method.
	(MemoryIdb.__InsertIssue): Remove.
	* qm/track/issue.py (IssueDifference): New class.
	(Issue.Copy): Rename to...
	(Issue.copy): ... this.
	(Issue.SetField): Add assert.
	(load_issues_from_xml_file): Remove.
	(_issues_from_dom): Likewise.
	(difference_issues): New function.
	(patch_issue): Likewise.
	(get_issues_from_dom_node): Likewise.
	(_get_field_values_from_dom_node): Likewise.
	(get_issue_from_dom_node): Likewise.
	(get_issue_difference_from_dom_node): Likewise.
	(get_histories_from_dom_node): Likewise.
	(get_history_from_dom_node): Likewise.
	(export_issues): Likewise.
	* qm/track/idb.py (IssueExistsError): New class.
	(IdbBase.__InvokeGetTriggers): Rename to...
	(IdbBase._InvokeGetTriggers): ... this.
	(IdbBase.__InvokePreupdateTriggers): Rename to...
	(IdbBase._InvokePreupdateTriggers): ... this.
	(IdbBase.__InvokePostupdateTriggers): Rename to...
	(IdbBase._InvokePostupdateTriggers): ... this.
	(import_issue_history): New function.
	* qm/track/config.py (setup_idb_for_internal_use): Add
	documentation to categories.  Add discussion field to
	enhancement_request class.
	* qm/track/cmdline.py: Adjust formatting.
	(Command.formats): Add export.
	(Command.__PerformCreate): Use IssueExistsError.
	(Command.__PerformSplit): Likewise.  Use copy.
	(Command.__PerformJoin): Likewise.
	(Command.__PerformImport): Rewrite.
	(Command.__ImportIssues): New method.
	(Command.__ImportIssueHistories): Likewise.
	(Command.__PrintResults): Handle export format.
	* qm/track/web/summary.py (handle_summary): Rewrite query
	determination logic.

	* share/xml/issue.dtd (histories): New element.
	(history): Likewise.
	(issue-difference): Likewise.
	* share/dtml/track/navigation-bar.dtml: Add banner.
	Don't copy requests.
	* share/diagnostics/track.txt (xml file no revision number): New
	diagnostic.
	(xml file nonconsecutive revisions): Likewise.
	(xml file unknown document element): Likewise.
	(xml file unknown field): Add quotes.

2001-06-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeLoginForm): Use AsForm.
	(WebRequest.AsForm): New method.
	(parse_url_query): Print warning instead of error response.
	(make_form_for_request): Remove.
	(make_properties_control): New function.
	(encode_properties): Likewise.
	(decode_properties): Likewise.
	* qm/fields.py (query_field_property_prefix): New variable.
	(FieldPropertyDeclaration): New class.
	(FieldEditPageInfo): Likewise.
	(Field.property_declarations): New attribute.
	(Field.__init__): Initialize properties from property_declarations.
	(Field.GetDescription): Don't specify default here.
	(Field.UnsetDefaultValue): Remove.
	(Field.HasDefaultValue): Likewise.
	(Field.GetAttribute): Make default for default_value None.  Check
	property_declarations for default. 
	(Field.IsAttribute): Default to false.
	(Field.GenerateEditWebPage): New method.
	(Field._MakeTextPropertyControl): Likewise.
	(Field._MakeBooleanPropertyControl): Likewise.
	(Field.MakePropertyControls): Likewise.
	(Field.UpdateFromRequest): Likewise.
	(IntegerField): Add doc string.
	(IntegerField.__init__): Pass default_value to base __init__.
	(IntegerField.GetHelp): Assume default value.
	(TextField): Revise doc string.
	(TextField.property_declarations): New attribute.
	(TextField.__init__): Don't initialize properties.
	(TextField.GetHelp): Assume default value.
	(TextField.MakePropertyControls): New method.
	(AttachmentField.__init__): Pass default value to base __init__.
	(EnumerationField.__init__): Likewise.
	(EnumerationField.GetHelp): Assume default value.
	(TimeField.GetTypeDescription): Use FormatValueAsText.
	(TimeField.FormatValueAsText): Accept None value.
	(UidField.__init__): Pass default to base __init__.

	* qm/track/server.py (start_server): Register config-idb,
	show-issue-field, submit-issue-class, submit-issue-field.
	* qm/track/memory_idb.py (MemoryIdb): Reorganize.
	(MemoryIdb.UpdateIssueClass): New method.
	* qm/track/issue_class.py (IidField.__init__): Add default_value
	parameter. 
	(IidField.SetDefaultValue): Rewrite.
	(IssueClass.__init__): Don't unset default value for iid.
	* qm/track/issue.py (Issue.__init__): Don't reat IID specially.
	(Issue.GetField): Return field's default value if none in issue.
	(Issue.SetField): Use GetClass.
	(Issue.DiagnosticPrint): Likewise.
	(Issue.Validate): Likewise.
	(Issue.MakeDomElement): Assume a default value.
	* qm/track/idb.py (IdbBase): Reorganize.
	* qm/track/cmdline.py (Command.__PerformCreate): Don't check for
	default value. 
	* qm/track/web/query.py (QueryPageInfo.MakeQueryForm): Use AsForm.
	* qm/track/web/issue_class.py (ShowPageInfo.GetFieldType): New
	method.
	(_get_issue_class_for_session): New function. 
	(handle_show): Rename to...
	(handle_show_class): ... this.  Rewrite.
	(handle_show_field): New function.
	(handle_submit_field): Likewise.
	(handle_config_idb): Likewise.
	(handle_submit_class): Likewise.
	* qm/track/web/index.py (IndexPageInfo.MakeNewForm): Use AsForm.
	(IndexPageInfo.MakeShowForm): Likewise.
	(IndexPageInfo.MakeQueryForm): Likewise.
	(IndexPageInfo.MakeLogoutForm): Likewise.

	* qm/test/cmdline.py (Command.__ExecuteServer): Revise URL message.

	* share/web/common.js: Adjust formatting.
	(property_add_or_change): New function.
	(property_remove): Likewise.
	(property_update_select): Likewise.
	* share/dtml/track/show.dtml: Close input element.
	* share/dtml/track/issue-class.dtml: Rewrite, practically.
	* share/dtml/track/index.dtml: Use MakeButton for administrative
	buttons.
	* share/dtml/field.dtml: New template.
	* share/dtml/track/config-idb.dtml: Likewise.

2001-06-11  Alex Samuel  <samuel@codesourcery.com>

	* share/dtml/track/show.dtml: Use an ordinary button for OK.

2001-06-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebServer.GetXmlRpcUrl): Use the explicitly-specified
	host name.
	(WebServer.Bind): Add messages.
	(WebServer.Run): Likewise.
	(handle_login): Close other sessions for same user.
	* qm/track/server.py (start_server): Print XML-RPC URL.
	* qm/track/cmdline.py: Reformat code.
	(Command.verbose_option_spec): New attribute.
	(Command.qmtrack_option_specs): Include it.
	(Command.GetGlobalOptions): Remove.
	(Command.GetCommandOptions): Likewise.
	(Command.HasGlobalOption): New method.
	(Command.GetGlobalOption): Likewise.
	(Command.HasCommandOption): Likewise.
	(Command.GetCommandOption): Likewise.
	Use them throughout.
	(Command.__Parse): Handle verbose option.
	* qm/track/qmtrack.in: Use GetGlobalOption.  Add messages. 

2001-06-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/web.py (PageInfo.GenerateStartBody): Use self as
	page info.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.common_javascript): Remove.
	(PageInfo.GenerateEndBody): Use _common_javascript.
	(_common_javascript): New variable.
	(_initialize_module): New function.
	Call it.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Generate from
	DTML. 
	(__initialize_module): Rename to...
	(_initialize_module): ... this.
	* qm/track/web/summary.py (handle_summary): Process last_query.
	* share/dtml/track/navigation-bar.dtml: New file.
	* share/web/common.js: Likewise.
	* share/web/stylesheets/qm.css (table.navbar): New class.
	(td.navbar): Likewise.
	(a.navbar): Likewise.
	
2001-06-10  Alex Samuel  <samuel@codesourcery.com>
	
	* share/dtml/user.dtml: New file.
	
2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (create_dom_text_element): Don't add child for
	empty string.
	* qm/web.py (PageInfo.__init__): Make request optional.
	(PageInfo.FormatUserId): Remove.
	(WebServer.__init__): Adjust for _handle_problems and
	_handle_root.
	(_get_path_for_cache_page): New function.
	(get_from_cache): Use it.
	(handle_problems): Rename to...
	(_handle_problems): ... this.
	(handle_root): Rename to...
	(_handle_root): ... this.
	(format_user_id): New function.
	* qm/user.py (xml_user_database_dtd): New variable.
	(User.__init__): Add property parameters.
	(XmlDatabaseUser): Remove class.
	(XmlDatabase.__init__): Remember path.  Use get_user_from_dom and
	get_group_from_dom. 
	(XmlDatabase.Write): New method.
	(get_user_from_dom): New function.
	(_get_dom_properties): Likewise.
	(create_dom_for_user): Likewise.
	(_create_dom_properties): Likewise.
	(get_group_from_dom): Likewise.
	(create_dom_for_group): Likewise.
	* qm/fields.py (UidField.FormatValueAsHtml): Use format_user_id.
	* qm/track/config.py (close_idb): Write user database.
	* share/web/stylesheets/qm.css (span.userid): Adjust.
	(a.userid): New class.
	* share/web/images/right-arrow.gif: New bitmap.
	* share/dtml/track/index.dtml: Adjust formatting.
	* share/dtml/track/history.dtml: Use bitmap arrow.  Adjust
	formatting. 

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (TimeField.GetCurrentTime): Return an int.
	* qm/track/web/web.py (HistoryPageInfo.GetRevisionTime): New method.
	* share/dtml/track/history.dtml: Use it.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* share/diagnostics/track.txt: Alphabetize.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.web): New attribute.
	* qm/common.py (Enumeral.__repr__): Fix typo.
	(Enumeral.__cmp__): Don't check strings against enumeration.
	* qm/track/web/summary.py (DisplayOptionsPageInfo.__init__): Check
	for no issue classes.
	(handle_summary): Handle all exceptions during queries.
	* qm/test/web/web.py (make_server): Register shutdown.
	(handle_shutdown): New function.
	* share/dtml/test/dir.dtml: Add shutdown button.
	* share/diagnostics/track.txt (query misc error): New diagonstic.
	(query name error): Likewise.
	(query syntax error): Likewise.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_linux.py (find_in_path): New function.
	(open_in_browser): Use it.
	(send_email): Use /usr/lib/sendmail as default.
	* doc/manual/common-manual.xml (sec-rc): New section.
	* doc/manual/test-reference.xml: Add link.
	* doc/manual/test-tour.xml: Likewise.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* configure.in (AC_CONFIG_SUBDIRS): Remove.
	* configure: Regenerate.
	
2001-06-08  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebServer.__init__): Register /.
	(handle_root): New function.
	* share/web/static/index.html: New file.
	* qm.spec (%files): Revert.

2001-06-08  Alex Samuel  <samuel@codesourcery.com>

	* qm.spec (%files): Add /usr/local/share/web/static/*.

2001-06-08  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.qm_bug_system_url): New variable.
	(PageInfo.GetMainPageUrl): New method.
	(PageInfo.GenerateEndBody): Add link to problems page.
	(WebServer.__init__): Register problems.html.
	(format_exception): Rewrite.
	(handle_problems): New function.
	* qm/track/web/web.py (PageInfo.GetMainPageUrl): New method.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Add
	open_only parameter.
	(DisplayOptionsPageInfo.__init__): Likewise.
	(handle_summary): Don't use IsDeleted.  Handle open_only field.
	* qm/track/server.py (start_server): Register /static.
	* qm/track/issue_class.py (State.__init__): Add open parameter.
	(State.IsOpen): New method.
	(StateModel.GetState): Convert state_name to string.
	(StateModel.GetOpenStateNames): New method.
	(_initialize_module): Set open flag for states.
	* qm/track/issue.py (Issue.IsDeleted): Remove.
	(Issue.IsOpen): New method.
	* qm/test/web/web.py (PageInfo.GetMainPageUrl): New method.
	(make_server): Register /static.
	* share/dtml/exception.dtml: New template.
	* share/dtml/problems.dtml: Likewise.
	* share/dtml/track/query.dtml: Align controls better.
	* share/dtml/track/summary-display-options.dtml: Add check box for
	open issues only.
	(do_ok): Process it.

2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/cmdline.py (Command.__WriteSummary): Order results with
	unexpected outcomes better.

2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.common_javascript): Add popup_manual.
	* qm/test/web/web.py (PageInfo.GenerateStartBody): Add manual link.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Likewise.
	* share/dtml/test/dir.dtml: Use GenerateEndBody.
	
2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebRequest.__init__): Copy client_address.
	* qm/fields.py (TimeField.GetDefaultValue): Use
	IntegerField.GetDefaultValue. 
	(TimeField.GetHelp): Use default_value attribute.
	* qm/track/issue.py (Issue.GetFieldAsText): New method.
	* qm/track/triggers/discussion.py (DiscussionTrigger.Preupdate):
	Use GetFieldAsText.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.__MakeMessage): Likewise.

2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (format_time): New function.
	(parse_time): Likewise.
	(timegm): Import or define here.
	* qm/fields.py (SetField.FormatValueAsHtml): Don't coerce to
	string here.
	(TimeField): Rewrite class.
	* tests/unit/common/format_time1.qmt: New test.
	* tests/unit/common/parse_time1.qmt: Likewise.
	* tests/unit/common/parse_time2.qmt: Likewise.
	* tests/unit/common/parse_time3.qmt: Likewise.
	* tests/unit/common/parse_time4.qmt: Likewise.
	
2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/classes/python.py (ExecTest.Run): Add expression value
	to failing result.
	* qm/test/cmdline.py (Command.add_test_id): Get rsh program from rc.
	* qm/test/base.py (CommandFailedError): New class.
	(SubprocessEngine._Run): Catch it.
	(CommandEngine.RunTests): Raise it.
	(RshEngine._Run): Likewise.
	* share/tutorial/test/tdb/exec0.qmt: New file.
	* share/tutorial/test/tdb/exec1.qmt: Likewise.
	* share/tutorial/test/tdb/exec2.qmt: Likewise.
	* share/tutorial/test/tdb/test1.qmt: Remove.
	* share/tutorial/test/tdb/test2.qmt: Likewise.
	* share/tutorial/test/tdb/_classes/count.py: Add descriptions.
	* doc/manual/test-tour.xml: Rewrite completely.
	* doc/manual/test-reference.xml: Document some command-line stuff.
	* doc/manual/test-manual.xml: Major revisions and additions.
	* doc/qm.mod (fixme): New entity.

2001-06-06  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (qmtest-cmd): New entity.
	(qmtrack-cmd): Likewise.
	* doc/manual/track-manual.xml (sec-issue-ids): New section.
	* doc/manual/test-manual.xml: Update.

2001-05-31  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py (RemoteTestHost.__init__): Change default qmtest
	path. 

2001-05-31  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/cmdline.py (Command.remote_option_spec): New attribute.
	(Command.conflicting_options_spec): Update.
	(Command.commands_spec): Add --remote-hosts option.
	(Command.add_test_id): Handle --remote-hosts option.
	* qm/test/base.py (RemoteTestHost): New class.
	(MultiProcessEngine): Generalize to...
	(SubprocessEngine): ... this new class.
	(MultiProcessEngine): New class.
	(MultiThreadEngine._Run): Don't call AsMap.
	(MultiRshEngine): New class.
	(RshEngine.__init__): Use RemoteTestHost instances.
	(RshEngine._Run): Likewise.

2001-05-31  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (load_xml_file): Split into...
	(load_xml): ... this new function.
	* qm/platform_linux.py (get_user_name): New function.
	* qm/platform_win32.py (get_user_name): Likewise.

	* qm/test/cmdline.py (Command.MakeContext): Look for
	--context-file and --context arguments at the same time.  Allow
	--context-file from stdin.
	(Command.add_test_id): Use MultiProcessEngine.
	(Command.__WriteResults): Use write_results.
	* qm/test/base.py (MultiThreadEngine): Generalize into... 
	(ConcurrentEngine): ... this.
	(MultiProcessEngine): New class.
	(MultiThreadEngine): Likewise.
	(CommandEngine): Reimplement, generalized.
	(LocalCommandEngine): New class.
	(RshEngine): Likewise.
	(write_results): New function.
	(save_results): Likewise.
	(read_results): Likewise.
	(load_results): Use it.
	(__results_from_dom): Rename to...
	(_results_from_dom): ... this.

2001-05-30  Alex Samuel  <samuel@codesourcery.com>

	* qm/structured_text.py (html_help_text): New variable.
	* qm/fields.py (TextField.FormatValueAsHtml): Show indication when
	editing structured text.
	(EnumerationField.__GetAvailableEnumerals): Add time zone.
	* qm/track/web/show.py (ShowPageInfo.FormatFieldValue): Handle
	user and timezone specially when editing.

2001-05-29  Alex Samuel  <samuel@codesourcery.com>

	* share/diagnostics/track-help.txt: New file.

2001-05-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/issue.py (Issue.GetField): Use field's default if the
	issue doesn't have a value.

2001-05-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_select): Add form_name parameter.
	* qm/track/web/query.py (QueryPageInfo.__init__): Don't get field
	names. 
	(QueryPageInfo.MakeQueryForm): Add name parameter.
	(QueryPageInfo.GetFieldTypeDescription): Remove.
	(QueryPageInfo.MakePythonQueryHelp): New method.
	(QueryPageInfo.MakeCategorySelect): Likewise.
	(QueryPageInfo.MakeStateSelect): Likewise.
	* qm/track/config.py (__initialize_module): Load help diagnostics.
	* share/dtml/track/query.dtml: Remove help info.  Add browse
	controls. 
	* share/dtml/track/index.dtml: Adjust labels for query.

2001-05-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (SetField.GetHtmlHelp): Don't add old help twice.
	* qm/common.py (Enumeral.__cmp__): Check RHS against enumerals for
	strings only.
	* qm/track/issue_class.py (IidField.__init__): copy attributes.
	(DiscussionField): New class.
	* qm/track/issue.py (Issue.MakeDomElement): Compare value as string.
	* qm/track/config.py (setup_idb_for_internal_use): Add discussion
	field.
	* qm/track/triggers/discussion.py: New file.
	* qm/track/web/web.py (HistoryPageInfo.FormatRevisionDiff): Handle
	set fields specially.
	
2001-05-28  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/test-manual.xml: Mention scheduling across threads
	and hosts.

2001-05-28  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/manual.xml: Include track-manual.xml.
	* doc/manual/track-manual.xml: New file.
	* doc/manual/test-manual.xml: Adjust.

2001-05-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/graph.py: Add doc string.
	(CycleError): New class.
	(__sort_helper): Handle node missing from edges map.
	(_partition): New function.
	(partition_as_map): Likewise.
	* qm/common.py (Lock): New class.
	(MutexMixin): Likewise.
	(OrderedMap.AsMap): New method.
	(print_message): Swap order of parameters.
	* share/diagnostics/test.txt (invalid concurrency): Likewise.
	* qm/test/xmldb.py (Database): Also derive from MutexMixin.
	(Database.GetClassPaths): Lock.
	(Database.HasTest): Likewise.
	(Database.GetTest): Likewise.
	(Database.WriteTest): Likewise.
	(Database.RemoveTest): Likewise.
	(Database.GetTestIds): Likewise.
	(Database.HasAction): Likewise.
	(Database.GetAction): Likewise.
	(Database.WriteAction): Likewise.
	(Database.RemoveAction): Likewise.
	(Database.GetActionIds): Likewise.
	* qm/test/cmdline.py (Command.concurrent_option_spec): New
	attribute.
	(Command.commands_spec): Include it.
	(Command.add_test_id): Handle --threads option.
	* qm/test/base.py (Engine): Rename to...
	(InProcessEngine): ... this.
	(Engine): New class.
	(MultiThreadEngine): Likewise.
	(CommandEngine): Likewise.
	(load_database): Adjust call to print_message.

2001-05-24  Alex Samuel  <samuel@codesourcery.com>

	* README: Mention Distutils.
	* qm/web.py (Session.__init__): Increase default timeout.
	* qm/platform_linux.py (RunProgramError): New class.
	(ProgramTerminateBySignalError): Likewise.
	(ProgramStoppedError): Likewise.
	(run_program_captured): Add doc string.  Use /dev/null for empty
	stdin.  
	(get_temp_directory): New function.
	* qm/platform.py (RunProgramError): Remove.
	(ProgramTerminateBySignalError): Likewise.
	(ProgramStoppedError): Likewise.
	* qm/label.py (thunk): Change + to x.
	(normpath): Remove multiple separators.
	(join): Normalize result.
	(to_path): Handle root path.
	(is_prefix): New function.
	* qm/fields.py (IntegerField.FormatValueAsHtml): Implement hidden
	style.
	(TextField.FormatValueAsHtml): Likewise.  Convert value to
	string.  Escape preformatted text.
	(SetField.FormatValueAsHtml): Implement hidden style.
	(EnumerationField.FormatValueAsHtml): Likewise.
	* qm/common.py (Enumeral.__cmp__): Check that RHS is valid enumeral.
	(load_module): Adjust Python path while loading module.
	(ends_with): New function.
	* share/dtml/test/suite.dtml: Adjust.
	* share/diagnostics/track.txt (address in use): Remove.
	* share/diagnostics/test.txt (unknown test or suite id): Adjust.
	* share/diagnostics/common.txt (address in use): New diagnostic.
	(could not read file): Likewise.
	* qm/track/qmtrack.in: Write message if KeyboardInterrupt.
	* qm/test/qmtest.in (program_name): Handle KeyboardInterrupt.
	* qm/test/cmdline.py (Command.context_file_spec): New attribute.
	(Command.commands_spec): Include it.
	(Command.MakeContext): Handle context-file option.
	(Command.__ParseContextAssignment): New method.
	(Command.add_test_id): Extract results from profile context.
	(Command.WriteSummary): Treat missing expected outcome as PASS.
	Adjust formatting.
	* qm/test/base.py (InstanceBase.SetWorkingDirectory): Use
	GetArguments. 
	(Suite.__init__): Initialize __test_id_cache.
	(Suite.GetTestIds): Cache result.
	(ResultWrapper.MakeDomNode): Handle sequence property values.
	(Engine.RunTests): Pass through KeyboardInterrupt.
	(load_database): Print warning when import fails.
	* qm/test/web/web.py (PageInfo.FormatTestId): Add within parameter.
	(PageInfo.FormatActionId): Likewise.
	(PageInfo.FormatSuiteId): Likewise.
	* qm/test/web/suite.py (ShowPageInfo.MakeAbsoluteId): New method.
	* qm/test/web/show.py (ShowPageInfo.IsShowField): Remove.
	(ShowPageInfo.FormatFieldValue): Handle hidden and read-only fields.

2001-05-22  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod: Add note.
	* doc/manual/test-manual.xml: Corrections.
	* doc/manual/test-tour.xml: Likewise.

2001-05-21  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (print_message): New function.
	(verbose): New variable.
	* qm/test/cmdline.py (Command.profile_option_spec): New attribute.
	(Command.commands_spec): Include it.
	(Command.Execute): Set global verbose value.
	(Command.add_test_id): Add profiling.
	* qm/test/base.py (Engine.null_function): Add messages.

2001-05-18  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py (_NotifyTrigger.Postupdate):
	Fix syntax error.

2001-05-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py (_NotifyTrigger.Postupdate):
	Set subject differently for new issues.

2001-05-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (escape): Don't handle empty strings specially.
	(make_help_link_html): Adjust spacing.
	* qm/fields.py (Field.FormatValueAsText): Add columns parameter.
	(Field.GetHtmlHelp): Mention field name at end.
	(IntegerField.FormatValueAsText): Add columns parameter.
	(TextField.FormatValueAsText): Likewise.
	(TextField.FormatValueAsHtml): Adjust output.
	(SetField.FormatValueAsText): Add columns parameter.
	(AttachmentField.FormatValueAsText): Likewise.
	(EnumerationField.FormatValueAsText): Likewise.
	* qm/common.py (indent_lines): New function.
	(wrap_lines): Likewise.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Add
	sort_order parameter.
	(handle_summary): Put sort order in user configuration.
	* qm/track/web/show.py (handle_submit): Don't format structured
	text errors here.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.__MakeMessage): Improve output format.
	* qm/track/server.py (start_server): Register path to manual.
	* qm/track/qmtrack.in: Set qm.common.program_name.
	* qm/track/issue_class.py (StateField.GetHelp): Fix spacing in
	enumeral list.
	* share/web/stylesheets/qm.css (span.error): Use darker red.
	* share/dtml/track/show.dtml: Space Help buttons.

2001-05-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeLoginForm): Adjust HTML.
	(PageInfo.UserIsInGroup): New method.
	(make_form_for_request): Add name parameter.
	(handle_login): Handle exceptions.
	* qm/user.py: Add doc string.
	(Group): New class.
	(DefaultDatabase.GetGroupIds): New method.
	(DefaultDatabase.GetGroup): Likewise.
	(XmlDatabase.__init__): Load groups.
	(XmlDatabase.GetGroupIds): New method.
	(XmlDatabase.GetGroup): Likewise.
	* qm/platform_linux.py (CLOSE_STREAM): New variable.
	(replace_program): New function.
	(run_program): Likewise.
	* qm/platform.py (RunProgramError): New class.
	(ProgramTerminatedBySignalError): Likewise.
	(ProgramStoppedError): Likewise.
	* qm/common.py (Empty): New class.
	* qm/track/web/index.py (IndexPageInfo.MakeNewForm): Specify form
	name. 
	(IndexPageInfo.MakeShowForm): Likewise.
	(IndexPageInfo.MakeEditForm): Remove.
	(IndexPageInfo.MakeShowAllForm): Likewise.
	(IndexPageInfo.MakeQueryForm): Specify form name.
	(IndexPageInfo.MakeShutdownForm): Likewise.
	(IndexPageInfo.MakeLogoutForm): Likewise.
	* qm/track/server.py (handle_shutdown): Disallow non-administrators. 
	
	* share/xml/users.xml.template: Add a group.
	* share/xml/user.dtd (users): Allow group elements.
	(group): New element.
	(user-id): Likewise.
	* share/web/stylesheets/qm.css (a.help-link): Don't specify
	decorations. 
	* share/dtml/track/index.dtml: Adjust buttons.  Show shutdown
	button for administrators only.
	* share/diagnostics/common.txt (disabled account): New diagnostic.
	(invalid login): Likewise.
	(shutdown not allowed): Likewise.

	* doc/manual/manual.xml (common-manual.xml): New entity.  Include it. 
	* doc/manual/common-manual.xml: New file.

2001-05-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.GetDefaultValue): Copy the result.
	* qm/common.py (copy): New function.
	* qm/track/server.py (start_server): Don't call get_host_name.
	* qm/test/cmdline.py (Command.Execute): Use load_database.
	* qm/test/base.py (Suite.GetTestIds): Use dirname.  Handle paths
	differently in implicit suites.
	(Database.GetPath): New method.
	(Database.GetClassPaths): Use _classes directory if it exists.
	(load_database): New function.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py
	(NotifyByUidFieldTrigger.Preupdate): Fix syntax.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py
	(NotifyByUidFieldTrigger.Preupdate): Don't subscribe a user twice.
	* qm/common.py (Enumeral.__cmp__): Handle TypeError.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py
	(NotifyByUidFieldTrigger.Preupdate): Handle new issues correctly.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/issue_class.py (IssueClass.__init__): Adjust default
	state model.
	* qm/track/issue.py (eval_revision_expression): Improve doc
	string.  Add _new to namespace.
	* qm/track/config.py (setup_idb_for_internal_use): Adjust.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.__MakeMessage): Handle new issues correctly.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform.py: Remove contents and split it into...
	* qm/platform_linux.py: ... this new file, and...
	* qm/platform_win32.py: ... this, likewise.
	* qm/track/server.py (execute): Let SignalException through.
	* qm/track/qmtrack.in: Handle SignalException.
	* qm/track/memory_idb.py (MemoryIdb.Close): Call __Write.
	(MemoryIdb.__Write): New method.
	(MemoryIdb.AddIssueClass): Call __Write.
	(MemoryIdb.__InsertIssue): Likewise.
	* qm/test/qmtest.in: Import qm.platform.

2001-05-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_url_for_request): Remove.
	Use AsUrl instead of make_url_for_request throughout.
	* qm/fields.py: Likewise.
	* qm/test/web/show.py: Likewise.
	* qm/test/web/suite.py: Likewise.
	* qm/test/web/web.py: Likewise.
	* qm/track/web/index.py: Likewise.
	* qm/track/web/show.py: Likewise.
	* qm/track/web/summary.py: Likewise.
	* qm/track/web/web.py: Likewise.
	
2001-05-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebRequestHandler.__HandlePageCacheRequest): New
	method. 
	(WebRequestHandler.__HandleSessionCacheRequest): Likewise.
	(WebRequestHandler.__HandleRequest): Call them.
	(WebRequest.AsUrl): New method.
	(make_set_control): Adjust for using page cache.
	(make_popup_dialog_script): Rename to...
	(make_popup_dialog): ... this and adjust for using page cache.
	(make_confirmation_dialog_script): Rename to...
	(make_confirmation_dialog): ... this, and remove function_name
	parameter. 
	(Session.make_button_for_popup): Reimplement using page cache.
	Leave old implementation, but disabled.
	(cache_page): New function.
	(get_from_cache): Likewise.
	(_page_cache_path): New variable.
	(_page_cache_name): Likewise.
	(_session_cache_name): Likewise.
	* qm/platform.py: Adjust formatting.
	* qm/fields.py (TextField.FormatValueAsHtml): Escape field values.
	(AttachmentField.FormatValueAsHtml): Use make_button_for_popup.
	* qm/common.py (make_temporary_directory): New function.
	(add_exit_function): Likewise.
	(_at_exit): Likewise.
	(_exit_functions): New variable.
	
	* share/diagnostics/common.txt (temp dir error): New diagnostic.
	* share/dtml/test/add-prerequisite.dtml: (add_prerequisite):
	Likewise.
	* share/dtml/test/add-category.dtml (add_category): Likewise.
	* share/dtml/test/add-action.dtml (add_action): Hard-code form
	field names. 
	* share/dtml/test/suite.dtml: Adjust for MakeDeleteScript.
	* share/dtml/test/show.dtml: Likewise.

	* qm/track/web/web.py (make_url_for_attachment): Stash attachment
	file name at end of URL.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Pass request
	to make_button_for_popup.
	* qm/test/web/web.py (PageInfo.FormatTestId): Add relative_to
	parameter. 
	(PageInfo.FormatActionId): Likewise.
	(make_server): Don't register add-action, add-category,
	add-prerequisite. 
	* qm/test/web/suite.py (ShowPageInfo.MakeDeleteScript): Adjust for
	make_confirmation_dialog. 
	* qm/test/web/show.py (ShowPageInfo.MakePrerequisitesControl):
	Generate page here for make_set_control.
	(ShowPageInfo.MakeActionsControl): Likewise.
	(ShowPageInfo.MakeCategoriesControl): Likewise.
	(ShowPageInfo.MakeDeleteScript): Adjust for make_confirmation_dialog.
	(AddPrerequisitePageInfo.__init__): Add base_path parameter.
	(AddActionPageInfo.__init__): Add action_path parameter.
	(handle_add_prerequisite): Remove.
	(handle_add_action): Likewise.
	(handle_add_category): Likewise.
	* qm/test/classes/python.py (ExecTest.fields): Set verbatim
	attribute on expression field.
	* qm/test/xmldb.py (Database.__GetPrerequisitesFromDomNode): Don't
	make IDs absolute here.
	(Database.__GetActionsFromDomNode): Likewise.
	(Database.__MakeDomNodeForTest): Don't reverse absolute IDs here.
	(Database.__MakeDomNodeForAction): Likewise.
	* qm/test/base.py (Test.GetPrerequisites): Add absolue parameter.
	(Test.GetActions): Likewise.
	(PrerequisiteMapAdapter.__getitem__): Use absolute IDs. 
	(Engine.null_function): Likewise, for prerequisites and actions.

2001-05-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/summary.py (DisplayOptionsPageInfo.__init__): Don't
	show hidden fields.
	* qm/track/config.py (setup_idb_for_test): Make the notification
	field hidden.

2001-05-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (scan_dir_for_suite_dirs): Skip directories
	named CVS.
	* qm/test/web/suite.py (ShowPageInfo.__init__): Construct controls
	for tests and suites here.
	* share/dtml/test/suite.dtml: Use test and suite controls from
	page info.

2001-05-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.common_javascript): Rename update_set to
	update_from_select_list.  Add move_option and swap_option.
	(__counter): Remove.
	(make_set_control): Use _counter.
	(_help_counter): Remove.
	(make_help_link_html): Use _counter.
	(make_select): Add default arguments.
	(make_choose_control): New function.
	(make_button_for_popup): Likewise.
	(_counter): New variable.
	* qm/fields.py (EnumerationField.GetTypeDescription): Fix quoting.
	(UidField.FormatValueAsHtml): Remove extraneous arguments to
	make_select. 
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Add
	field_names parameter.  Generate display options page.
	(SummaryPageInfo.IsLinkToIssue): Remove.
	(DisplayOptionsPageInfo): New class.
	(handle_summary): Figure out fields to show.
	* share/dtml/track/summary.dtml: Add Display Options button.
	Adjust. 
	* share/dtml/track/summary-display-options.dtml: New file.

	* doc/manual/manual.xml: Fix title.

2001-05-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_select): New function.
	* qm/user.py (DefaultDatabase.keys): New method.
	(XmlDatabase.keys): Likewise.
	* qm/fields.py (EnumerationField.FormatValueAsHtml): Use
	make_select.
	(UidField.FormatValueAsHtml): New method.
	* share/xml/users.xml.test-values: New file.
	* qm/track/config.py (initialize_idb): Add test_values parameter.
	Initialize test values and test user database.
	* qm/track/cmdline.py (Command.__PerformInitialize): Don't
	generate test values here.

2001-05-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_javascript_string): Don't escape slashes.
	* qm/platform.py: New class.
	(MailError.send_email): New function.
	* qm/fields.py (Field.FormatValueAsText): New method.
	(IntegerField.FormatValueAsText): Likewise.
	(TextField.FormatValueAsText): Likewise.
	(SetField.FormatValueAsText): Likewise.
	(AttachmentField.FormatValueAsText): Likewise.
	(EnumerationField.FormatValueAsText): Likewise.
	(UidField.__init__): Use default user ID as default value.
	* qm/common.py (RcConfiguration.Get): Return default if no rc file
	loaded. 
	* share/diagnostics/common.txt (sendmail error): New diagnostic.
	* qm/track/triggers/state.py (Trigger.Preupdate): Call
	eval_revision_expression. 
	* qm/track/triggers/notification.py: New file.
	* qm/track/qmtrack.in: Load rc file.
	* qm/track/issue.py (eval_expression): Replace with...
	(eval_issue_expression): ... this.
	(eval_revision_expression): New function.
	* qm/track/idb.py (IdbBase.Query): Call eval_issue_expression.
	* qm/track/config.py (setup_idb_for_test): Add notification stuff.
	
2001-05-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (parse_url_query): Unquote the script URL.
	(make_javascript_string): Escape forward slashes.
	* qm/common.py (Enumeral): New class.
	* qm/fields.py (Field.__init__): Add initialze_to_default attribute. 
	(Field.GetAttributeNames): New method.
	(EnumerationField.__init__): Make an Enumeral.
	(EnumerationField.GetTypeDescription): Use enumeral strings.
	(EnumerationField.Validate): Rewrite.
	(EnumerationField.GetEnumerals): Modify for Enumeral.
	(EnumerationField.ValueToName): Remove.
	(EnumerationField.ParseFormValue): Make an Enumeral.
	(EnumerationField.FormEncodeValue): Use enumeral string.
	(EnumerationField.FormDecodeValue): Make an Enumeral.
	(EnumerationField.FormatValueAsHtml): Modify for Enumeral.
	(EnumerationField.MakeDomNodeForValue): Likewise.
	(EnumerationField.GetHelp): Likewise.
	(EnumerationField.__GetAvailableEnumerals): New method.

	* qm/track/web/show.py (ShowPageInfo.__init__): Rename
	field_errors to errors.  Process structured text.
	(ShowPageInfo.FormatFieldValue): Handle initialize_to_default
	attribute. 
	(handle_submit): Handle trigger rejections.
	* qm/track/triggers: New directory.
	* qm/track/triggers/__init__.py: New file.
	* qm/track/triggers/state.py: Likewise.
	* qm/track/web/issue_class.py: Likewise.
	* qm/track/server.py (start_server): Register show-issue-class.
	* qm/track/memory_idb.py (MemoryIdb.GetIssue): Fix parameter name
	collision.  Adjust trigger treatment.
	(MemoryIdb.GetAllRevisions): Likewise.
	(MemoryIdb.__InsertIssue): Likewise.
	* qm/track/sql_idb.py (SqlIdb.GetIssues): Likewise.
	(SqlIdb.GetIssue): Likewise.
	(SqlIdb.GetAllRevisions): Likewise.
	(remap): Remove crud.
	(pprint_ast): Likewise.
	* qm/track/issue_class.py (default_states): Remove.
	(default_state_model): New variable.
	(default_state_model): New class.
	(default_state_model): Likewise.
	(TriggerResult): Likewise.
	(Trigger): Likewise.
	(State): Likewise.
	(TransitionCondition): Likewise.
	(Transition): Likewise.
	(StateModel): Likewise.
	(StateField): Likewise.
	(IssueClass.__init__): Replace states parameter with state_model.
	Initialize __triggers.  Create the state field.
	(IssueClass.RegisterTrigger): New method.
	(IssueClass.GetTriggers): Likewise.
	(_initialize_module): New function.
	Call it.
	* qm/track/issue.py (eval_expression): New function.
	(allowed_builtins): New variable.
	(_initialize_module): New function.
	Call it.
	* qm/track/idb.py (Trigger): Remove.
	(TriggerOutcome): Likewise.
	(TriggerRejectError): New class.
	(IdbBase.__init__): Remove __triggers attribute.
	(IdbBase.RegisterTrigger): Remove.
	(IdbBase.UnregisterTrigger): Likewise.
	(IdbBase.GetTriggers): Likewise.
	(IdbBase.Query): Call eval_expression instead of rexec stuff.
	(IdbBase.__InvokeGetTriggers): Rewrite.
	(IdbBase.__InvokePreupdateTriggers): Likewise.
	(IdbBase.__InvokePostupdateTriggers): Likewise.
	* qm/track/cmdline.py (Command.__PerformInitialize): Process
	structured text message. 

	* share/dtml/track/show.dtml: Adjust markup to show errors.
	* share/dtml/track/issue-class.dtml: New file.
	* share/diagnostics/track.txt (no changes): New diagonstic.
	(no transition): Likewise.
	(not initial state): Likewise.
	(transition condition failed): Likewise.

2001-05-01  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (RcConfiguration.Get): Remove mention of DEFAULT.
	Use section parameter correctly.
	* qm/platform.py: New file.
	* qm/test/web/web.py (start_server): Rename to...
	(make_server): ... this.  Return server instead of running it.
	* qm/test/xmldb.py (Database.GetClassPaths): New method.
	* qm/test/cmdline.py (Command.start_browser_option_spec): New
	variable. 
	(Command.commands_spec): Use it.  Remove edit and template
	commands. 
	(Command.HasGlobalOption): New method.
	(Command.HasCommandOption): Likewise.
	(Command.__ExecuteEdit): Remove.
	(Command.__EditTest): Likewise.
	(Command.__ExecuteTemplate): Likewise.
	(Command.__ExecuteServer): Start browser if requested.
	* qm/test/base.py (Database.GetClassPaths): New method.
	(get_class): Remove extra_paths parameter.  Use the database's
	class paths.
	* share/tutorial/test/tdb/_classes/: New directory.
	* share/tutorial/test/count.py: Move to...
	* share/tutorial/test/tdb/_classes/count.py: ... here.
	* share/diagnostics/test-help.txt (action class control): Mention
	_classes subdirectory.
	(test class control): Likewise.
	* share/diagnostics/common.txt (browser error): New diagnostic.
	* doc/manual/manual.xml: Include test-reference.xml.
	* doc/manual/test-manual.xml: Add section on specifying test classes. 
	* doc/manual/test-reference.xml: New file.
	
2001-04-30  Benjamin Chelf  <chelf@codesourcery.com>

	* install.bat: New file.

2001-04-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtest/core.xml: Paste in text from design document.

2001-04-30  Alex Samuel  <samuel@codesourcery.com>

	* Makefile.in (PYTHONDOCDIRS): Comment out.
	* install.py (doc_files): Add manual PDF file.
	(doc_dirs): New variable.
	Substitute @qm_doc_path2 in setup_path.py.
	Install documentation directories.
	* qm/Makefile.in (setup_path.py): Substitute @qm_doc_path@.
	* qm/setup_path.py.in (__doc_dir): New variable.
	Set QM_DOC_PATH environment variable.
	* qm/common.py (get_doc_directory): New function.
	* qm/test/web/web.py (start_server): Register manual directory.
	* qm/web.py (PageInfo.html_generator): Remove.
	(session_id_field): In show_help, open window with toolbar and
	scrollbars options.
	(PageInfo.GetProgramName): New method.
	(PageInfo.GenerateHtmlHeader): Use it.
	(make_help_link_html): Generate page from DTML.
	* share/dtml/help.dtml: New file.
	* doc/Makefile.in (SUBDIRS): Remove design doc directories.
	* doc/manual/Makefile.in (DOCBOOKMAIN): Change to manual.xml.
	* doc/manual/main.xml: Rename to...
	* doc/manual/manual.xml: ... this.

2001-04-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/web/web.py (start_server): Register delete-test,
	delete-action, and delete-suite scripts.
	* qm/test/web/suite.py (ShowPageInfo.MakeDeleteScript): New method.
	(handle_delete): New function.
	* qm/test/web/show.py (ShowPageInfo.MakeDeleteScript): New method.
	(handle_delete): New function.
	* qm/test/xmldb.py (Database.RemoveTest): New method.
	(Database.RemoveAction): Likewise.
	(Database.RemoveSuite): Likewise.
	* qm/test/base.py (Database.RemoveTest): New method.
	(Database.RemoveSuite): Likewise.
	(Database.RemoveAction): Likewise.
	* qm/web.py (make_popup_dialog_script): New function.
	(make_confirmation_dialog_script): Likewise.
	(make_popup_page): Likewise.
	* share/web/stylesheets/qm.css (body.popup): New class.
	* share/dtml/test/show.dtml: Add Delete button.
	* share/dtml/test/suite.dtml: Likewise.

2001-04-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_help_link_html): Use a.help-link CSS class.
	* qm/test/xmldb.py (Database.__GetSuite): Don't make IDs absolute.
	* qm/test/web/web.py (start_server): Register create-suite and
	new-suite scripts.
	* qm/test/web/suite.py: Improve doc strings.
	(ShowPageInfo.__init__): Fix exclusion of suite's own ID.
	(NewPageInfo): New class.
	(handle_submit): Handle empty ID lists correctly.
	(handle_new): New function.
	(handle_create): Likewise.
	* share/diagnostics/test-help.txt (suite ID): New diagnostic.
	* share/diagnostics/test.txt (suite already exists): Likewise.
	* share/web/stylesheets/qm.css (a.help-link): New class.
	* share/dtml/test/suite.dtml: Adjust.
	* share/dtml/test/new-suite.dtml: New file.

2001-04-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeUrl): New method.
	(make_url): New function.
	* qm/test.py: Remove file.
	* qm/test/web/web.py (PageInfo.FormatSuiteId): New method.
	(start_server): Register edit-suite, show-suite, submit-suite
	scripts. 
	* qm/test/web/suite.py: New file.
	* qm/test/web/dir.py (DirPageInfo.FormatItem): Use FormatSuiteId.
	* qm/test/cmdline.py (Command.__ExecuteRun): Process arguments
	here. 
	(Command.__ExecuteEdit): Use "unknown test id" diagnostic.
	(Command.__WriteResults): Use base.dtds.
	* qm/test/xmldb.py (Database.WriteTest): Likewise.
	(Database.WriteAction): Likewise.
	(Database.GetSuite): Use __GetSuite.
	(Database.WriteSuite): New method.
	(Database.GetSuiteIds): Handle implicit parameter.
	(FileSuite): Remove.
	(DirectorySuite): Reimplement.
	(scan_dir_for_suite_dirs): New function.
	* qm/test/base.py (dtds): New variable.
	(InstanceBase.__MakeItem): New method.
	(Test.GetTest): Use it.
	(Action.GetAction): Likewise.
	(Suite): Reimplement.
	(Database.GetSuiteIds): Add implicit parameter.
	(get_all_test_ids): Remove.
	(expand_and_validate_ids): Likewise.

	* share/xml/CATALOG: Add suite DTD.
	* share/xml/suite.dtd: New file.
	* share/dtml/test/suite.dtml: New file.
	* share/diagnostics/test.txt (no id for edit): Generalize.
	(no id for show): Likewise.
	(no id for submit): Likewise.
	(unknown id): Remove.
	(unknown test id): New diagnostic.
	(unknown test or suite id): Likewise.
	* share/diagnostics/test-help.txt (suite suite IDs): New
	diagnostic.
	(suite suite IDs control): Likewise.
	(suite test IDs): Likewise.
	(suite test IDs control): Likewise.

	* tests/unit/common/label_thunk.qmt: Remove test for thunk of
	empty label.
	* tests/common.qms: Convert to XML format.

2001-04-26  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.common_javascript): Add help_window.  Add
	show_help.
	(PageInfo.MakeHelpButton): Remove.
	(PageInfo.MakeHelpLink): New method.
	(PageInfo.MakeHelpLinkHtml): Likewise.
	(make_set_control): Make popup resizable.  Change popup window
	logic.
	(make_help_button): Remove.
	(make_help_link): New function.
	(_help_counter): New variable.
	(make_help_link_html): New function.
	* qm/structured_text.py (HtmlFormatter.__verbatim_regex): Match at
	start of line.
	(HtmlFormatter.__strong_regex): Likewise.
	(HtmlFormatter.__emph_regex): Likewise.
	* qm/fields.py (Field.GetHelp): New method.
	(Field.GetHtmlHelp): Likewise.
	(IntegerField.GetHelp): Likewise.
	(TextField.GetHelp): Likewise.
	(SetField.FormatValueAsHtml): Specify window size.
	(SetField.GetHelp): New method.
	(SetField.GetHtmlHelp): Likewise.
	(AttachmentField.FormatValueAsHtml): Rename button "Change..."
	(AttachmentField.GetHelp): New method.
	(AttachmentField.GetHtmlHelp): Likewise.
	(EnumerationField.GetHelp): Likewise.
	(UidField.__init__): Pass attributes to base.
	* qm/diagnostic.py (DiagnosticSet.program_name): Remove.
	(DiagnosticSet.Generate): Use common.program_name.
	* qm/common.py (program_name): New variable.
	* qm/Makefile.in ($(SCRIPTS)): Use PYTHONBIN.
	* qm/track/config.py (setup_idb_for_test): Adjust syntax.  Add
	descriptions. 
	* qm/track/issue_class.py (IssueClass.__init__): Likewise.
	(IidField.__init__): Pass attributes to base.
	* qm/test/qmtest.in: Set common.program_name.  Load help diagnostics.
	* share/dtml/attachment.dtml: Add help links.
	* share/dtml/test/add-action.dtml: Likewise.
	* share/dtml/test/add-category.dtml: Likewise.
	* share/dtml/test/add-prerequisite.dtml: Likewise.
	* share/dtml/test/new.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/dtml/track/show.dtml: Likewise.
	* share/diagnostics/common-help.txt: New file.
	* share/web/stylesheets/qm.css (body): Specify font-family.
	(a:link): Don't specify background.
	(a:visited): Likewise.
	(a:active): Likewise.
	(a:hover): Likewise.
	
2001-04-25  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/Makefile.in: Fix typo.

2001-04-25  Alex Samuel  <samuel@codesourcery.com>
	
	* qm/xmlutil.py (write_dom_document): Don't write emacs gunk.
	* qm/web.py (PageInfo.common_javascript): New attribute.
	(PageInfo.FormatStructuredText): New method.
	(PageInfo.GenerateEndBody): Include common JavaScript.
	(PageInfo.MakeButton): New method.
	(PageInfo.MakeUrlButton): Reimplement.
	(PageInfo.MakeHelpButton): New method.
	(WebRequest.GetScriptName): Likewise.
	(make_url_button): Remove.
	(make_button_for_request): New function.
	(make_button_for_url): Likewise.
	(generate_error_page): Likewise.
	(__counter): New variable.
	(make_set_control): New function.
	(encode_set_control_contents): Likewise.
	(decode_set_control_contents): Likewise.
	(make_javascript_string): Likewise.
	(make_help_button): Likewise.
	* qm/label.py (UnmakeRelativeTo.__call__): Handle empty path case.
	(basename): New function.
	(dirname): Likewise.
	* qm/structured_text.py (get_first): Likewise.
	(get_rest): Likewise.
	* qm/fields.py (Field.SetAttributes): New method.
	(IntegerField.ParseFormValue): Catch ValueError.
	(AttachmentField.__init__): Pass attributes to base __init__.
	(TextField.__init__): Call SetAttributes.
	(TextField.FormatValueAsHtml): Replace qm.web with web.
	(SetPopupPageInfo): New class.
	(SetField.FormatValueAsHtml): Reimplement editable case.
	(UploadAttachmentPageInfo): New class.
	(AttachmentField.attachment_summary_prefix): Remove.
	(AttachmentField.FormatValueAsHtml): Capitalize None.
	Reimplement editable case.
	(AttachmentField.GenerateFormValue): Handle null case.
	(AttachmentField.FormatSummary): Adjust.
	(EnumerationField.ParseFormValue): New method.
	(EnumerationField.FormEncodeValue): Likewise.
	(EnumerationField.FormDecodeValue): Likewise.
	(EnumerationField.FormatValueAsHtml): Add a hidden control.
	* qm/diagnostic.py (help_set): New variable.
	(__initialize_module): Load common-help.txt.
	* qm/common.py (convert_from_dos_text): Swap CR LF order.
	(starts_with): New function.
	* qm/attachment.py (upload_url): New constant.
	(temporary_attachment_dir): Likewise.
	(_temporary_location_prefix): Likewise.
	(register_attachment_upload_script): New function.
	(_path_for_temporary_attachment): Likewise.
	(is_temporary_attachment_location): Likewise.
	(_next_temporary_location): New variable.
	(get_temporary_location): New function.
	(store_temporary_attachment): Likewise.
	(retrieve_temporary_attachment): Likewise.
	(handle_attachment_upload): Likewise.

	* qm/track/web/web.py (UploadAttachmentPageInfo): Remove.
	(handle_upload_attachment): Likewise.
	(handle_submit_attachment): Likewise.
	(generate_error_page): Likewise.
	* qm/track/web/show.py (ShowPageInfo.__init__): Rename
	invalid_fields to field_errors.
	(retrieve_attachment_data): New function.
	(handle_submit): Use it.  Handle exceptions better.
	* qm/track/server.py (start_server): Call
	register_attachment_upload_script.  Remove submit-addatchment and
	upload-attachment scripts.

	* qm/test/classes/temporary.py (TempDirectoryAction.fields): Add
	default values.
	(TempDirectoryAction.__init__): Remove default arguments.
	* qm/test/classes/python.py (ExecTest.fields): Use text fields
	instead of attachment fields.
	(ExecTest.__init__): Adjust accordingly.
	(BaseExceptionTest.fields): Use text fields instead of attachment
	fields.
	(BaseExceptionTest.__init__): Adjust accordingly.
	(ExceptionTest.fields): Adjust.
	(ExceptionTest.__init__): Remove default arguments.
	(StringExceptionTest.__init__): Likewise.
	* qm/test/classes/command.py (CommandTest.__init__): Remove
	default arguments.  Handle null interpreter.
	* qm/test/xmldb.py (TestFileError): Derive from RuntimeError.
	(Database.GetTest): Handle DomNodeError.
	(Database.GetTestIds): New method.
	(Database.HasAction): Likewise.
	(Database.WriteAction): Likewise.
	(Database.GetActionIds): Likewise.
	(Database.GetSuiteIds): Likewise.
	(Database.SetAttachmentData): Likewise.
	(Database.__InvalidateItem): Likewise.
	(Database.__MakeDomNodeForTest): Rewrite.
	(Database.__MakeDomNodeForAction): New method.
	(Database.__MakeDomNodeForItem): Likewise.
	(scan_dir_for_labels): New function.
	* qm/test/qmtest.in (print_error_message): Process structued text. 
	* qm/test/cmdline.py (Command.port_option_spec): New attribute.
	(Command.address_option_spec): Likewise.
	(Command.log_file_option_spec): Likewise.
	(Command.commands_spec): Add server command.
	(Command.GetGlobalOption): Add default parameter.
	(Command.GetCommandOption): Likewise.
	(Command.Execute): Set global database.  Don't set __database
	attribute. 
	(Command.GetDatabase): Use get_database.
	(Command.__ExecuteServer): New method.
	(Command.__ExecuteTemplate): Use make_new_test.
	* qm/test/base.py (standard_test_class_names): New variable.
	(standard_action_class_names): Likewise.
	(InstanceBase.__init__): Validate the ID.
	(Test.GetTest): Use default field values.
	(Database.GetTestIds): New method.
	(Database.WriteSuite): Likewise.
	(Database.GetSuiteIds): Likewise.
	(Database.HasAction): Likewise.
	(Database.GetAction): Likewise.
	(Database.WriteAction): Likewise.
	(Database.GetActionIds): Likewise.
	(Database.SetAttachmentData): Likewise.
	(validate_id): New function.
	(get_database): Likewise.
	(get_all_test_ids): Likewise.
	(make_new_test): Likewise.
	(make_new_action): Likewise.
	(_database): New variable.

	* qm/test/web/: New directory.
	* qm/test/web/__init__.py: New file.
	* qm/test/web/dir.py: Likewise.
	* qm/test/web/show.py: Likewise.
	* qm/test/web/web.py: Likewise.

	* tests/unit/common/graph_complete.qmt: Adjust for test class changes.
	* tests/unit/common/graph_cycle.qmt: Likewise.
	* tests/unit/common/graph_pass.qmt: Likewise.
	* tests/unit/common/label_is_valid.qmt: Likewise.
	* tests/unit/common/label_thunk.qmt: Likewise.
	* tests/unit/common/parser_create.qmt: Likewise.
	* tests/unit/common/parser_dup_command_long.qmt: Likewise.
	* tests/unit/common/parser_dup_command_short.qmt: Likewise.
	* tests/unit/common/parser_duplicate_long.qmt: Likewise.
	* tests/unit/common/parser_duplicate_short.qmt: Likewise.
	* tests/unit/common/parser_help.qmt: Likewise.
	* tests/unit/common/parser_no_long.qmt: Likewise.
	* tests/unit/common/parser_parse.qmt: Likewise.
	* tests/unit/common/parser_two_char_short.qmt: Likewise.
	
	* share/web/stylesheets/qm.css (a:link): Underlinke links.
	(a:visited): Likewise.
	(a:active): Likewise.
	(a:hover): Likewise.
	(body.help): New class.
	(a.reverse): Likewise.
	(tr.heading): Likewise.
	* share/dtml/attachment.dtml: New file.
	* share/dtml/error.dtml: Likewise.
	* share/dtml/set.dtml: Likewise.
	* share/dtml/test/add-action.dtml: Likewise.
	* share/dtml/test/add-category.dtml: Likewise.
	* share/dtml/test/add-prerequisite.dtml: Likewise.
	* share/dtml/test/dir.dtml: Likewise.
	* share/dtml/test/new.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/dtml/track/error.dtml: Remove.
	* share/dtml/track/upload-attachment.dtml: Likewise.
	* share/dtml/track/show.dtml: Adjust.
	* share/diagnostics/common.txt (invalid enum key): New diagnostic.
	(invalid integer field value): Likewise.
	* share/diagnostics/test.txt (action already exists): Likewise.
	(class not found): Likewise.
	(error loading xml test): Likewise.
	(invalid class name): Likewise.
	(invalid test id): Likewise.
	(missing argument): Likewise.
	(no id for show): Likewise.
	(no id for submit): Likewise.
	(no such action): Likewise.
	(no such test): Likewise.
	(invalid id): Remove.

2001-04-23  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/Makefile.in: Add CYGWIN to setup_path.py generation.

	* configure.in (AC_CHECK_FILE): Change exit to a warning.
	* configure: Regenerate.

	* configure.in (AC_CHECK_FILE): Remove Makefile.pre.in.
	* configure: Regenerate.

2001-04-18  Benjamin Chelf  <chelf@codesourcery.com>

	* Makefile.in (setup): Remove generation of extension modules.
	* configure.in (AC_OUTPUT): Add sqmlop/Makefile and
	zope-dtml/ExtensionClass/Makefile.
	* configure: Regenerate.
	* sgmlop/Makefile.in: New file.
	* sgmlop/setup.py: Likewise.
	* zope-dtml/ExtensionClass/Makefile.in: Likewise.
	* zope-dtml/ExtensionClass/setup.py: Likewise.

2001-04-13  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/label.py (thunk): Remove rand. Change to raise exception.

2001-04-09  Alex Samuel  <samuel@codesourcery.com>

	* qm/diagnostic.py (message): New function.
	* qm/__init__.py: Import message from diagnostic.
	* share/diagnostics/test.txt (test did not raise): New diagnostic.
	(test raised non-object): Likewise.
	(test raised non-string): Likewise.
	(test raised wrong argument): Likewise.
	(test raised wrong class): Likewise.
	(test raised wrong string): Likewise.
	(unknown test class): Likewise.
	* qm/test/classes/python.py: New file.
	* qm/test/xmldb.py (UnknownTestClassError): Fix typo.  Derive from
	RuntimeError. 
	(UnknownActionClassError): Likewise.
	(Database.__ParseTestDocument): Handle ImportError.

	* tests/common.qms: New suite.
	* tests/unit/common/graph_complete.qmt: New test.
	* tests/unit/common/graph_cycle.qmt: Likewise.
	* tests/unit/common/graph_pass.qmt: Likewise.
	* tests/unit/common/label_is_valid.qmt: Likewise.
	* tests/unit/common/label_thunk.qmt: Likewise.
	* tests/unit/common/parser_create.qmt: Likewise.
	* tests/unit/common/parser_dup_command_long.qmt: Likewise.
	* tests/unit/common/parser_dup_command_short.qmt: Likewise.
	* tests/unit/common/parser_duplicate_long.qmt: Likewise.
	* tests/unit/common/parser_duplicate_short.qmt: Likewise.
	* tests/unit/common/parser_help.qmt: Likewise.
	* tests/unit/common/parser_no_long.qmt: Likewise.
	* tests/unit/common/parser_parse.qmt: Likewise.
	* tests/unit/common/parser_two_char_short.qmt: Likewise.
	* tests/unit/test/classes/tempdir1.qmt (<class>): Use
	python.ExecTest. 

2001-04-08  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/: New directory.
	* doc/manual/Makefile.in: New file.
	* doc/manual/main.xml: Likewise.
	* doc/manual/introduciton.xml: Likewise.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.
	
	* qm/test/base.py (Engine.RunTests): Adjust handling of
	action dependencies and context properties.

2001-04-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (action_file_extension): New variable.
	(UnknownActionClassError): New exception class.
	(Database.__init__): Initialize __actions.
	(Database.HasTest): Use __HasItem.
	(Database.HasAction): New method.
	(Database.GetTest): Use __GetItem.
	(Database.GetAction): New method.
	(Database.__HasItem): Likewise.
	(Database.__GetItem): Likewise.
	(Database.__ParseTestDocument): Parse actions.
	(Database.__ParseActionDocument): New method.
	(Database.__GetClassNameFromDomNode): Generalize.
	(Database.__GetArgumentsFromDomNode): Likewise.
	(Database.__GetActionsFromDomNode): New method.
	* qm/test/cmdline.py (Command.__ProgressCallback): Simplify.
	(Command.__ExecuteTemplate): Use get_class.
	(Command.divider): Improve error messages.
	* qm/test/base.py (NoSuchActionError): New class.
	(InstanceBase): Likewise.
	(Test): Derive from InstanceBase. 
	(Test.__init__): Add some parameter defaults.  Add actions
	parameter. 
	(Test.GetClassName): Remove.
	(Test.GetClass): Likewise.
	(Test.GetArguments): Likewise.
	(Test.GetId): Likewise.
	(Test.GetActions): New method.
	(Test.Run): Set working directory.
	(Action): New class.
	(Result.GetOutcome): New method.
	(ResultWrapper.GetContextProperties): Likewise.
	(Context): Don't validate values.
	(Context.__ValidateKey): Rename to...
	(Context.ValidateKey): ... this.
	(Context.__ValidateValue): Remove.
	(ContextWrapper): New class.
	(Engine.RunTests): Reorganize.  Add actions.  Add context property
	handling code. 
	(make_result_for_exception): Add outcome parameter.
	(get_test_class): Generalize to...
	(get_class): ... this.
	(__loaded_test_classes): Generalize to...
	(__loaded_classes): ... this.
	(__builtin_test_class_path): Generalize to...
	(__builtin_class_path): ... this.
	* qm/test/classes/temporary.py: New file. 
	* qm/test/classes/python.py: Likewise.

	* share/diagnostics/test.txt (context attribute cannot be deleted): 
	New diagnostic.
	* share/xml/CATALOG (fields.mod): New entry.
	* share/xml/fields.mod: New DTD module.
	* share/xml/issue.dtd: Use shared fields module.
	* share/xml/test.dtd: Likewise.
	* share/xml/action.dtd: New file.
	
	* tests/unit/test/classes/tempdir1.qmt: New file.
	* tests/unit/test/classes/tempdir1.qma: Likewise.

2001-04-03  Alex Samuel  <samuel@codesourcery.com>

	* README: Update.
	* qm/test/qmtest.in: Fix import.
	* share/tutorial/: New directory.
	* share/tutorial/test/: Likewise.
	* share/tutorial/test/tdb/: Likewise.
	* share/tutorial/test/count.py: New file.
	* share/tutorial/test/tdb/test1.qmt: Likewise.
	* share/tutorial/test/tdb/test2.qmt: Likewise.
	
2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* install.py: Fix order.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk.in (INSTALLDOCDIR): New variable.
	* qm.spec (files): Include doc files.
	* install.py (doc_files): New variable.
	Take doc dir as argument.  Install documentation.
	* README: Improve formatting.  Describe new track features, and
	add test tutorial.
	* Makefile.in (install): Pass doc directory to install script.
	* share/diagnostics/test.txt (missing test id): New diagnostic.
	(test class not fully specified): Likewise.
	* qm/test/cmdline.py (Command.__ExecuteRun): Handle ValueError.
	(Command.__ExecuteTemplate): Likewise.
	(Command.divider): Generate an indication if no tests failed, or
	if no tests produced unexpected outcomes.
	* qm/test/base.py (get_test_class): Fix typo.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* qm.spec (BuildRoot): Reove.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* qm/setup_path.py.in (add_to_python_path): Use __lib_dir.
	(__base_dir): Remove.
	(__lib_dir): New variable.
	(__share_dir): Likewise.
	Set different environment variables.
	* qm/fields.py (EnumerationField.__init__): Adjust call to base
	initializer.  Set default.
	(TimeField.__init__): Likewise.
	* qm/common.py (get_base_directory): Remove.
	(get_lib_directory): New function.
	(get_share_directory): Likewise.
	* qm/Makefile.in (setup_path.py): Adjust substitutions.
	* qm/track/config.py (initialize_idb): Get user db template from
	new location.
	* qm/track/cmdline.py (Command.__PerformInitialize): Print a
	message. 
	* qm/test/base.py (__builtin_test_class_path): Use
	get_lib_directory in initializer.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* Makefile.in (install): New target.
	* configure.in (AC_PROG_INSTALL): Use it.
	* configure: Regenerate.
	* install.py: New file.
	* qm.spec: Likewise.
	* standard.mk.in (INSTALL): New variable.
	(prefix): Likewise.
	(exec_prefix): Likewise.
	(INSTALLBINDIR): Likewise.
	(INSTALLLIBDIR): Likewise.
	(INSTALLSHAREDIR): Likewise.
	* sgmlop/sgmllib.py: Strip CR.
	* sgmlop/xmllib.py: Likewise.
	* xmlrpc/xmlrpc_handler.py: Likewise.
	* xmlrpm/xmlrpclib.py: Likewise.
	* share/diagnostics/track.txt (new idb message): New diagnostic.
	* qm/users.xml.tempalte: Move to...
	* share/xml/users.xml.template: ... here.

2001-03-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (write_dom_document): Write emacs configury.
	(__hyphen_regex): New variable.
	(__hyphen_replacement): New function.
	(sanitize_text_for_comment): Likewise.
	* qm/structured_text.py (to_text): Add width and indent
	parameters.
	* qm/label.py (MakeRelativeTo.__init__): Remove label parameter.
	(UnmakeRelativeTo): New class.
	* qm/common.py (is_executable): New function.
	* qm/attachment.py (make_dom_node): Handle 'None' attachments.
	(from_dom_node): Likewise.
	* qm/fields.py (AttachmentField.MakeDomNodeForValue): Likewise.
	
	* share/xml/test.dtd (attachment): Allow empty element.
	* share/diagnostics/test.txt (invalid class): New diagnostic.
	(mising arg for template): Likewise.
	(no id for edit): Likewise.
	(test already exists): Likewise.
	(unknown id): Likewise.

	* qm/test/xmldb.py (Database.WriteTest): New method.
	(Database.TestIdToPath): New method.
	(Database.__GetClass): Rename to...
	(Database.__GetClassNameFromDomNode): ... this.
	(Database.__GetArguments): Rename to...
	(Database.__GetArgumentsFromDomNode): ... this.
	(Database.__GetPrerequisites): Rename to...
	(Database.__GetPrerequisitesFromDomNode): ... this.
	(Database.__MakeDomNodeForTest): New method.
	(FileSuite.__init__): Adjust for MakeRelativeTo.
	(DirectorySuite.__AddTestsInDirectory): Likewise.
	* qm/test/cmdline.py (Command.commands_spec): Add edit and
	template commands.
	(Command.Execute): Dispatch edit and template.
	(Command.__ExecuteEdit): New method.
	(Command.__EditTest): Likewise.
	(Command.__ExecuteTemplate): Likewise.
	(Command.divider): Print cause on ERROR outcome.
	* qm/test/base.py (Test.__init__): Take test class name as
	parameter. 
	(Test.GetClassName): New method.
	(Test.GetClass): Adjust.
	(Test.GetArguments): New method.
	(Test.GetCategories): Likewise.
	(Database.WriteTest): Likewise.
	(ResultWrapper.MakeDomElement): Rename to...
	(ResultWrapper.MakeDomNode): ... this.
	* qm/test/classes/command.py (ExecTest.__init__): Make stdin
	default to None.
	(ExecTest.Run): Initialize result_pipe_file.  Handle null
	attachment for stdin, stdout, stderr.  Fix pipe cleanup.
	(ExecTest.RunProgram): Check executable.  Catch access error.
	(CommandTest.__init__): Make stdin default to None.
	(CommandTest.RunProgram): Check interpreter executable.
	(ScriptTest.__init__): Make stdin default to None.

2001-03-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.__init__): Make attributes parameter a
	catch-all for named arguments.
	(IntegerField.__init__): Add attributes parameter.
	(TextField.__init__): Likewise.
	(AttachmentField.__init__): Likewise.
	(EnumerationField.__init__): Likewise.
	(TimeField.__init__): Likewise.
	* qm/common.py (format_exception): Use format_traceback.
	(format_traceback): New function.
	(decode_data_from_text): Add none encoding.
	(open_temporary_file_fd): New function.
	(open_temporary_file): Likewise.
	(find_program_in_path): Likewise.
	* qm/attachment.py (from_dom_node): Make description, mimetype,
	filename elements optional.
	* share/xml/test.dtd (attachment): Make subelements optional.
	(data): New element.
	* share/diagnostics/common.txt (dom wrong tag for field): Fix.
	(temp file error): New diagnostic.
	* share/diagnostics/test.txt (invalid context assignment): Likewise.
	(invalid environment assignment): Likewise.
	(xml invalid arg name): Fix.
	(xml not int value): Likewise.
	* qm/test/base.py (Context.__ValidateKey): Raise ValueError.
	(Engine.RunTests): Use make_result_for_exception.
	(make_result_for_exception): New function.
	* qm/test/cmdline.py (Command.context_option_spec): New attribute.
	(Command.commads_spec): Add it to the run command.
	(Command.MakeContext): New method.
	(Command.__ExecuteRun): Use it.
	* qm/test/classes/command.py: New file.

2001-03-26  Alex Samuel  <samuel@codesourcery.com>

	Reorganize data files into share directory.

	* qm/xmlutil.py (make_system_id): Adjust.
	(load_xml_file): Use get_share_directory.
	* qm/web.py (PageInfo.html_stylesheet): New attribute.
	(PageInfo.html_generator): Likewise.
	Rename _login_url request field to _redirect_url throughout.
	(PageInfo.default_class): Set it.
	(WebRequestHandler.__HandleScriptRequest): Catch NoSessionError
	and InvalidSessionError.
	(WebServer.HandleNoSessionError): New method.
	(WebRequest.GetSession): Raise NoSessionError.
	(Session.Validate): Raise InvalidSessionError.
	(get_session): Likewise.
	(handle_logout): New function.
	(generate_html_from_dtml): Likewise.
	(generate_login_form): Likewise.
	* qm/diagnostic.py (DiagnosticSet.ReadFromFile): Change path
	parameter. 
	(__initialize_module): New function.  Call it.
	* qm/diagnostics.txt: Remove.
	* qm/common.py (get_base_directory): Add components parameter.
	(get_share_directory): New function.
	* qm/track/web/web.py (PageInfo.html_stylesheet): Remove.
	(__initialize_module): New function.  Call it.
	(generate_html_from_dtml): Use generioc generate_html_from_path.
	* qm/track/web/index.py (IndexPageInfo.MakeLogoutForm): Set
	_redirect_url. 
	* qm/track/server.py (start_server): Use get_share_directory.
	Register logout.  
	* qm/track/config.py (__initialize_module): New function.  Call
	it. 
	* qm/test/qmtest.in: Use get_share_directory.

	* qm/dtds/CATALOG: Remove.
	* qm/dtds/issue.dtd: Likewise.
	* qm/dtds/result.dtd: Likewise.
	* qm/dtds/test.dtd: Likewise.
	* qm/dtds/user.dtd: Likewise.
	* qm/test/diagnostics.txt: Likewise.
	* qm/track/diagnostics.txt: Likewise.
	* qm/track/web/images/clear.gif: Likewise.
	* qm/track/web/images/sc-logo.png: Likewise.
	* qm/track/web/stylesheets/qmtrack.css: Likewise.
	* qm/track/web/templates/error.dtml: Likewise.
	* qm/track/web/templates/history.dtml: Likewise.
	* qm/track/web/templates/index.dtml: Likewise.
	* qm/track/web/templates/query.dtml: Likewise.
	* qm/track/web/templates/show.dtml: Likewise.
	* qm/track/web/templates/summary.dtml: Likewise.
	* qm/track/web/templates/upload-attachment.dtml: Likewise.
	* qm/dtds/: Remove directory.
	* qm/track/web/images/: Likewise.
	* qm/track/web/templates/: Likewise.
	
	* share/: New directory.
	* share/diagnostics/: Likewise.
	* share/dtml/: Likewise.
	* share/dtml/track/: Likewise.
	* share/web/: Likewise.
	* share/web/images/: Likewise.
	* share/web/stylesheets/: Likewise.
	* share/xml/: Likewise.
	* share/diagnostics/common.txt: New file.
	* share/diagnostics/test.txt: Likewise.
	* share/diagnostics/track.txt: Likewise.
	* share/dtml/login_form.dtml: Likewise.
	* share/dtml/track/error.dtml: Likewise.
	* share/dtml/track/history.dtml: Likewise.
	* share/dtml/track/index.dtml: Likewise.
	* share/dtml/track/query.dtml: Likewise.
	* share/dtml/track/show.dtml: Likewise.
	* share/dtml/track/summary.dtml: Likewise.
	* share/dtml/track/upload-attachment.dtml: Likewise.
	* share/web/images/clear.gif: Likewise.
	* share/web/images/sc-logo.png: Likewise.
	* share/web/stylesheets/qm.css: Likewise.
	* share/xml/CATALOG: Likewise.
	* share/xml/issue.dtd: Likewise.
	* share/xml/result.dtd: Likewise.
	* share/xml/test.dtd: Likewise.
	* share/xml/user.dtd: Likewise.
	
2001-03-25  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py (load_results): Use load_xml_file.

2001-03-25  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (ParseError): New class.
	(make_system_id): New function.
	(load_xml_file): Likewise.
	(get_dom_text): Handle empty text.
	(create_dom_document): Generate system ID from DTD file name.
	* qm/web.py (session_id_field): New variable.
	(NoSessionError): New class.
	(InvalidSessionError): Likewise.
	(PageInfo.MakeLoginForm): New method.
	(PageInfo.FormatUserId): Likewise.
	(WebRequestHandler.do_GET): Store client IP address in request.
	(WebRequestHandler.do_POST): Likewise.
	(WebRequestHandler.__HandleScriptRequest): Set no-cache header.
	(WebRequestHandler.__HandleFileRequest): Set public caching.
	(WebServer.Bind): Set SO_REUSEADDR.
	(WebRequest.__init__): Add base parameter.
	(WebRequest.SetSessionId): New method.
	(WebRequest.GetSessionId): Likewise.
	(WebRequest.GetSession): Likewise.
	(WebRequest.get): Likewise.
	(WebRequest.copy): Add url, fields parameters.
	(Session): New class.
	(get_session): New function.
	(__clean_up_expired_sessions): Likewise.
	(handle_login): Likewise.
	(sessions): New variable.
	* qm/user.py: New file.
	* qm/users.xml.template: Likewise.
	* qm/diagnostics.txt (bad port number): New diagnostic.
	(xml parse error): Likewise.

	* qm/dtds: New directory.
	* qm/dtds/CATALOG: New file.
	* qm/dtds/issue.dtd: Likewise.
	* qm/dtds/reslt.dtd: Likewise.
	* qm/dtds/test.dtd: Likewise.
	* qm/dtds/user.dtd: Likewise.

	* qm/track/server.py (start_server): Handle index and login pages.
	* qm/track/issue.py (issues_to_xml): Use public ID and DTD file
	name.
	* qm/track/diagnostics.txt (xml parse error): Remove.
	* qm/track/config.py (open_idb): Load user database.
	(initialize_idb): Create user database from template.
	* qm/track/cmdline.py (Command.__PerformServer): Handle bad port
	numbers.
	* qm/track/issue.dtd: Remove.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Adjust title
	bar. 
	(UploadAttachmentPageInfo.MakeSubmitUrl): Copy request.
	* qm/track/web/summary.py (SummaryPageInfo.MakeIssueUrl): Copy
	request. 
	* qm/track/web/query.py (QueryPageInfo.MakeQueryForm): Likewise.
	* qm/track/web/show.py (ShowPageInfo.MakeSubmitUrl): Likewise.
	(handle_submit): Likewise. Set the user field.
	* qm/track/web/index.py (IndexPageInfo.MakeNewForm): Copy request.
	(IndexPageInfo.MakeShowForm): Likewise.
	(IndexPageInfo.MakeEditForm): Likewise.
	(IndexPageInfo.MakeShowAllForm): Likewise.
	(IndexPageInfo.MakeQueryForm): Likewise.
	(IndexPageInfo.MakeQueryUrl): Likewise.
	(IndexPageInfo.MakeShutdownForm): Likewise.
	(IndexPageInfo.MakeLogoutForm): New method.
	* qm/track/web/templates/index.dtml: Reformat.  Add login controls.
	* qm/track/web/stylesheets/qmtrack.css: Adjust formatting.
	(span.userid): New style.

	* qm/test/xmldb.py (Database.GetTest): Use load_xml_file.
	* qm/test/cmdline.py (Command.__WriteResults): Use public ID and
	DTD file name.
	* qm/test/results.dtd: Remove.
	* qm/test/test.dtd: Likewise.
	
2001-03-22  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (create_dom_text_element): New function.
	(__dom_implementation): New variable.
	(create_dom_document): New function.
	(write_dom_document): Likewise.
	* qm/web.py (WebRequestHandler.do_GET): Ignore exceptions during
	shutdown. 
	(WebRequestHandler.do_POST): Likewise.
	(WebRequestHandler.__HandleScriptRequest): Ignore IO errors during
	write. 
	* qm/fields.py (Attachment): Remove.
	Use attachment.Attachment throughout.
	Replace qm.track.error with qm.error throughout.
	(Field.__repr__): New method.
	(Field.MakeDomNodeForValue): Likewise.
	(IntegerField.MakeDomNodeForValue): Likewise.
	(TextField.MakeDomNodeForValue): Likewise.
	(SetField.MakeDomNodeForValue): Likewise.
	(AttachmentField.MakeDomNodeForValue): Likewise.
	(EnumerationField.MakeDomNodeForValue): Likewise.
	* qm/common.py (encode_data_as_text): New function.
	(decode_data_from_text): Likewise.
	* qm/attachment.py: New file.

	* qm/track/sql_idb.py (SqlIdb.AddIssue): Check IID uniqueness.
	(SqlIdb.__ColumnSpecForField): Add fourth attachment column.
	(SqlIdb.__GetColumnName): Likewise.
	(SqlIdb.__BuildSqlForFieldValue): Likewise.
	(SqlIdb.__GetFieldFromRow): Likewise.
	* qm/track/issue.py (IssueFileError): New class.
	(Attachment): Likewise.
	(Issue.__repr__): New method.
	(Issue.MakeDomElement): Likewise.
	(get_differing_fields): Ignore revision number and timestamp.
	(load_issues_from_xml_file): New function.
	(__issues_from_dom): Likewise.
	(__issue_from_dom): Likewise.
	(issues_to_xml): Likewise.
	Initialize qm.attachment.attachment_class.
	* qm/track/issue.dtd: New file.
	* qm/track/idb.py (IdbBase.Query): Ignore attachment fields.
	* qm/track/diagnostics.txt (missing import files): New diagnostic.
	(xml file unknown class): Likewise.
	(xml file unknown field): Likewise.
	(xml parse error): Likewise.
	(format error): Add output format specifier. 
	* qm/track/cmdline.py (Command.output_option): New attribute.
	(Command.qmtrack_commands): Use it for several commands.  Add
	import command.
	(Command.__init__): Dispatch import command.
	(Command.Execute): Handle output option.
	(Command.__PerformQuery): Query all issue classes.
	(Command.__PerformImport): New method.
	(Command.__PrintResults): Adjust comments.  Implement XML format.
	* qm/track/web/web.py (make_url_for_attachment): Use attachment
	attributes. 
	
	* qm/test/test.dtd: Adjust for attachment schema.
	* qm/test/cmdline.py (Command.__WriteResults): Use
	create_dom_document and write_dom_document.
	* qm/test/base.py (Attachment): New class.
	Initialize qm.attachment.attachment_class.

2001-03-20  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py: New file.
	* qm/fields.py: Use it throughout.
	* qm/common.py (OrderedMap.__len__): New method.
	(get_dom_node_text): Remove.
	(get_child_dom_node_text): Likewise.
	(get_dom_children_texts): Likewise.
	* qm/cmdline.py (CommandParser.__init__): Add conflicting_options
	parameter.
	(CommandParser.ParseCommandLine): Check for conflicting options.
	* qm/diagnostics.txt (conflicting options): New diagnostic.

	* qm/test/xmldb.py: Use qm.xmlutil throughout.
	* qm/test/cmdline.py (Command.all_results_option_spec): Remove.
	(Command.verbose_option_spec): New attribute.
	(Command.output_option_spec): Likewise.
	(Command.no_output_option_spec): Likewise.
	(Command.summary_option_spec): Likewise.
	(Command.no_summary_option_spec): Likewise.
	(Command.outcomes_option_spec): Likewise.
	(Command.conflicting_option_specs): Likewise.
	(Command.commands_spec): Add options.
	(Command.__init__): Use conflicting_option_specs.
	(Command.Execute): Handle verbose option.
	(Command.__ExecuteRun): Handle summary, output, and outcome
	options.
	(Command.__ProgressCallback): New method.
	(Command.__WriteSummary): Likewise.
	(Command.__WriteResults): Rewrite.
	* qm/test/base.py (Result.__init__): Remove context parameter.
	(Result.__getitem__): Remove.
	(Result.get): Likewise.
	(ResultWrapper): New class.
	(Engine.RunTests): Add progress_callback parameter.  Wrap results
	in ResultWrapper.
	(load_outcomes): New function.
	(load_results): Likewise.
	(__results_from_dom): Likewise.
	(__result_from_dom): Likewise.
	* qm/test/diagnostics.txt (class is not test class): Remove.
	* qm/test/results.dtd: New file.
	* qm/test/test.dtd: Add comments.

2001-03-20  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/sql_idb.py (SqlIdb.GetIssues): import types. 
	(SqlIdb.GetIssue): Change type IssueClass to
	qm.track.issue_class.IssueClass to fix bug.
	(SqlIdb.GetAllRevisions): Likewise.

2001-03-18  Alex Samuel  <samuel@codesourcery.com>

	* qm/graph.py: Fix code formatting.
	* qm/common.py (OrderedMap): New class.
	* qm/test/cmdline.py (Command.all_results_option_spec): New
	variable.
	(Command.commands_spec): Include it.
	(Command.__init__): Initialize __show_all_results.
	(Command.Execute): Handle all-results option.
	(Command.__ExecuteRun): Show all results if specified.
	* qm/test/base.py (Test.__init__): Add parameters.
	(Test.GetTest): New method.
	(Test.GetClass): Likewise.
	(Test.AddCategory): Remove.
	(Test.GetPrerequisites): New method.
	(Test.Run): Use GetTest.
	(Result.outcomes): New variable.
	(Result.__str__): Reimplement.
	(Result.get): New method.
	(PrerequisiteMapAdapter): New class.
	(Engine.RunTests): Handle prerequisites.
	* qm/test/xmldb.py (Database.__DOES_NOT_EXIST): New constant.
	(Database.__NOT_LOADED): Likewise.
	(Database.__init__): Initialize test and suite caches.
	(Database.HasTest): Use caches.
	(Database.GetTest): Likewise.
	(Database.HasSuite): Likewise.
	(Database.GetSuite): Likewise.
	(Database.__ParseTestDocument): Parse prerequisites.  Pass info to
	Test initializer.
	(Database.__GetArguments): Treat fields as list.
	(Database.__GetPrerequisites): Get outcome attribute.
	* qm/test/test.dtd (prerequisite): Add attlist.
	* qm/test/diagnostics.txt (invalid result): New diagnostic.

2001-03-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (__label_regex): Remove.
	(__Label_regex_with_dot): Likewise.
	(is_valid_label): Likewise.
	(__label_thunk_regex): Likewise.
	(thunk_to_label): Likewise.
	(get_dom_children_texts): New function.
	* qm/label.py: New file.
	* qm/fields.py: Use qm.label.
	* qm/test.py: Likewise.
	* qm/test/xmldb.py: Use qm.label.
	(Database.GetTest): Fix typo.
	(Database.__ParseTestDocument): Rename parameter.  Read categories
	and prerequisites.
	(Database.__GetPrerequisites): New method.
	(FileSuite.__init__): Improve path handling.
	(DirectorySuite.__init__): Likewise.
	(DirectorySuite.__AddTestsInDirectory): Likewise.
	Don't load diagnostics.  Don't load RC.
	* qm/test/qmtest.in (print_error_message): Remove self parameter.
	Initialize qmtest diagnostics.  Load RC.  Fix error message.
	* qm/test/base.py: Use qm.label.
	(Test.IsInCategory): New method.
	(Test.AddCategory): Likewise.
	* qm/track/issue_class.py: Use qm.label.

2001-03-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/Makefile.in (SCRIPTS): New variable.
	(all): Remove track/qmtrack.  Add $(SCRIPTS).
	(track/qmtrack): Generalize to...
	(%: %.in): ... this rule.
	* qm/test/cmdline.py (Command.__WriteOutcomes): Wrap apply
	argument in a tuple.

2001-03-16  Alex Samuel  <samuel@codesourcery.com>

	* README: Update requirements.
	* qm/__init__.py: Import error and warning.
	* qm/diagnostic.py: Add doc string.  Improve comments.
	(DiagnosticSet.__init__): Don't take program name.  Don't load.
	(DiagnosticSet.ReadFile): Rename to...
	(DiagnosticSet.ReadFromFile): ... this.
	(DiagnosticSet.Generate): Rewrite.
	(error): New function.
	(warning): Likewise.
	(diagnostic_set): New variable.
	Initialize generic diagnostics.
	* qm/diagnostics.txt: New file.
	* qm/setup_path.py.in: Put base directory in environment.
	* qm/common.py (base_directory): Remove.
	(get_base_directory): Get from environment.
	(RcConfiguration): New class.
	(__label_regex_with_dot): New variable.
	(is_valid_label): Add allow_periods parameter.
	(get_host_name): Improve comments.
	(format_byte_count): Use constants.
	(get_dom_node_text): New function.
	(get_child_dom_node_text): Likewise.
	(load_module): Likewise.
	(load_class): Likewise.
	(split_path_fully): Likewise.
	(rc): New variable.
	* qm/cmdline.py (CommandParser.GetBasicHelp): Adjust output.
	(CommandParser.GetCommandHelp): Likewise,
	* qm/fields.py (DomNodeError): New class.
	(Field.GetTypeDescription): New method.
	(Field.GetValueFromDomNode): Likewise.
	(IntegerField.GetTypeDescription): Likewise.
	(IntegerField.GetValueFromDomNode): Likewise.
	(TextField.GetTypeDescription): Likewise.
	(TextField.GetValueFromDomNode): Likwise.
	(SetField.GetTypeDescription): Likewise.
	(SetField.GetValueFromDomNode): Likewise.
	(AttachmentField.GetTypeDescription): Likewise.
	(AttachmentField.GetValueFromDomNode): Likewise.
	(EnumerationField.GetTypeDescription): Likewise.
	(EnumerationField.GetValueFromDomNode): Likewise.a
	(TimeField.GetTypeDescription): Likewise.
	(UidField.GetTypeDescription): Likewise.

	* qm/track/__init__.py: Import error and warning.
	* qm/track/qmtrack.in: Use diagnostic "missing idb".
	* qm/track/issue_class.py (IidField.GetTypeDescription): New method.
	* qm/track/idb.py (get_field_type_description_for_query): Remove.
	* qm/track/diagnostics.txt (command error): Remove.
	(missing idb): New diagnostic.
	* qm/track/config.py (__diagnostics): Remove.
	(diagnostic): Likewise.
	(error): Likewise.
	(warning): Likewise.
	Load diagnostics.
	* qm/track/cmdline.py (Command.command): Remove.
	(Command.Execute): Use "missing command" diagnostic.

	* qm/track/web/query.py (QueryPageInfo.GetFieldTypeDescription):
	Use GetTypeDescription method. 
	* qm/track/web/templates/summary.dtml: Show groupings only if
	there is more than one issue class.  Improve formatting.
	* qm/track/web/stylesheets/qmtrack.css (th.issue_class): Set
	background-color to grey.

	* qm/test: New directory.
	* qm/test/__init__.py: New file.
	* qm/test/base.py: Likewise.
	* qm/test/cmdline.py: Likewise.
	* qm/test/diagnostics.txt: Likewise.
	* qm/test/qmtest.in: Likewise.
	* qm/test/test.dtd: Likewise.
	* qm/test/xmldb.py: Likewise.
	* qm/test/classes: New directory.
	* qm/test/classes/__init__.py: New file.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PrivilegedPortError): New class.
	(WebServer.Bind): Handle EACCES.
	* qm/track/server.py (start_server): Handle PrivilegedPortError.
	* qm/track/diagnostics.txt (privileged port): New diagnostic.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/config.py (diagnostic): Generate path to diagnostics
	file. 

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (EnumerationField.FormatValueAsHtml): Fix name and
	value defaults.
	* qm/track/config.py (setup_idb_for_internal_use): Don't generate
	issues. 

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/templates/index.dtml: Fix typo.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebServer.__init__): Add address parameter.
	(WebServer.Bind): Use __address.
	* qm/track/server.py (start_server): Add address parameter.
	* qm/track/cmdline.py (Command.address_option): New variable.
	(Command.qmtrack_commands): Use it.
	(Command.__PerformServer): Handle address option.
	
2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/structured_text.py (TextFormatter.__init__): Set default
	width to 78.  Initialize __depth.
	(TextFormatter.StartList): Don't indent outermost paragraphs.
	(TextFormatter.EndList): Likewise.
	(to_text): Fix comment.
	* qm/cmdline.py (CommandParser.GetOptionsHelp): Adjust output.
	(CommandParser.GetCommandHelp): Treat command description as
	structured text. 

	* qm/track/issue_class.py (IssueClass.__init__): Add title and
	description. 
	(IssueClass.GetTitle): New method.
	(IssueClass.GetDescription): Likewise.
	* qm/track/idb.py (IdbBase.Query): Don't handle multiple issue
	classes here.
	* qm/track/sql_idb.py (SqlIdb.Query): Likewise.
	(SqlIdb.__AddResults): Remove.
	* qm/track/config.py (setup_idb_for_internal_use): New function.
	(setup_idb_for_test): Set class title.
	* qm/track/cmdline.py (Command): Update option descriptions.
	(Command.internal_option): New variable.
	(Command.qmtrack_commands): Use it.
	(Command.__PerformInitialize): Handle internal option.

	* qm/track/web/summary.py (SummaryPageInfo.__init__): Partition
	issues by class.  Handle reverse sort.
	(SummaryPageInfo.MakeResortUrl): Indicate reverse sort where
	appropriate. 
	(handle_summary): Loop over issue classes when querying.
	* qm/track/web/index.py (IndexPageInfo.__init__): Extract issue
	classes for IDB. 
	* qm/track/web/stylesheets/qmtrack.css (th.issue_class): New
	style. 
	* qm/track/web/templates/summary.dtml: Show issues grouped by
	class. 
	* qm/track/web/templates/show.dtml: Print class for new issue.
	* qm/track/web/templates/index.dtml: Show select for issue class
	for new issue.

2001-03-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebRequestHandler.do_GET): Flush and shut down
	socket.
	* qm/fields.py: New file.

	* qm/track/issue.py: Likewise.
	(Attachment): Remove.
	* qm/track/diagnostics.txt (field exist): Don't use class as a
	parameter name. 
	* qm/track/cmdline.py (Command.__CheckFieldTypes): Don't use class
	as a parameter name.  Use qm.field.

	* qm/track/web/web.py: Use qm.field.
	(form_field_prefix): Remove.
	(attachment_description_prefix): Likewise.
	(attachment_mime_type_prefix): Likewise.
	(attachment_location_prefix): Likewise.
	(attachment_file_name_prefix): Likewise.
	(make_form_field_value): Likewise.
	(format_field_value): Likewise.
	(format_int_field_value): Likewise.
	(format_text_field_value): Likewise.
	(format_set_field_value): Likewise.
	(format_enum_field_value): Likewise.
	(format_attachment_field_value): Likewise.
	(make_url_for_attachment): Add field argument.  Insert into
	AttachmentField. 
	* qm/track/web/show.py (handle_submit): Use qm.field.
	(ShowPageInfo.FormatFieldValue): Handle read_only and
	initialize_only attributes.
	(validate_mime_type): Remove.
	(extract_attachment_field_value): Likewise.
	(decode_set_field_value): Likewise.
	(handle_submit): Simplify, using qm.field.
	* qm/track/sql_idb.py: Use qm.field.
	* qm/track/test.py: Likewise.
	* qm/track/config.py (setup_idb_for_test): Likewise.
	* qm/track/idb.py: Likewise.
	* qm/track/issue_class.py (IssueField): Remove.
	(IssueFieldInteger): Likewise.
	(IssueFieldText): Likewise.
	(IssueFieldSet): Likewise.
	(IssueFieldAttachment): Likewise.
	(IssueFieldEnumeration): Likewise.
	(IssueFieldTime): Likewise.
	(IssueFieldUid).
	(IssueClass.__init__): Use qm.field.
	* qm/track/web/templates/upload-attachment.dtml: Use new
	attachment encoding.

2001-03-13  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/test.py (test_graph_cycle): Define.
	(test_graph_complete): Likewise.
	(test_graph_pass): Likewise.
	(regression_tests): Add the above.
	* qm/graph.py: New file.

2001-03-09  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/diagnostics.txt: Add new error messages.
	* qm/track/cmdline.py: Fixed formatting for raising errors.

2001-03-05  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/show.py (handle_submit): Format error messages.
	* qm/track/server.py (start_server): Handle address in use errors.
	(execute): Issue diagnostics.
	* qm/track/issue_class.py: Use diagnostics throughout.
	(IssueFieldText.Validate): Convert from DOS text.
	* qm/track/diagnostics.txt: New file.
	* qm/track/config.py (__diagnostics): New variable.
	(diagnostic): New function.
	(error): Likewise.
	(warning): Likewise.
	* qm/track/cmdline.py (Command.__PerformDestroy): Handle lock error.

	* qm/web.py (AddressInUseError): New class.
	(WebServer.Bind): Raise it.
	(escape): Reimplement.
	(__entity_regex): New variable.
	(__replacement_for_entity): New function.
	(unescape): New function.
	(format_structured_text): Reimplement.
	* qm/diagnostic.py: New file.
	* qm/structured_text.py: Likewise.
	* qm/common.py (FileSystemMutex.GetPath): New method.
	(MapReplacer): New class.
	(replace_by_map): New function.
	(convert_from_dos_text): Likewise.

2001-03-01  Alex Samuel  <samuel@codesourcery.com>

	* README: Adjust tutorial.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Adjust
	navigation bar. 
	* qm/track/config.py (setup_idb_for_test): Ajust titles.
	* qm/track/issue_class.py (IssueClass.__init__): Likewise.
	* qm/track/cmdline.py (Command.__PrintResults): Add full format
	style.

2001-03-01  Alex Samuel  <samuel@codesourcery.com>

	* README: Update.
	* qm/web.py (WebRequestHandler.__HandleScriptRequest): Handle
	SystemExit. 
	(WebServer.__init__): Initialize __shutdown_requested.
	(WebServer.Run): Run until shutdown request.
	(WebServer.RequestShutdown): New method.
	* qm/common.py (remove_directory_recursively): New function.
	* qm/track/web/templates/show.dtml: Use field title.
	* qm/track/web/templates/index.dtml: Adjust.  Add shutdown.
	* qm/track/web/images/sc-logo.png: New file.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Adjust title
	bar. 
	* qm/track/web/index.py (IndexPageInfo.MakeShutdownForm): New
	method. 
	* qm/track/issue_class.py (default_categories): Adjust.
	(IssueField.GetTitle): New method.
	(IssueField.GetDescription): Likewise.
	(IssueFieldSet.__init__): Use attributes from contained field.
	(IssueClass.__init__): Adjust mandatory fields.
	* qm/track/config.py (get_idb_lock): New function.
	(open_idb): Use it.
	(setup_idb_for_test): Adjust test values.
	* qm/track/cmdline.py: Adjust command descriptions.  Add destroy
	command. 
	(Command.__init__): Register destroy.
	(Command.__PerformDestroy): New method.

2001-02-28  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/sql_idb.py (Query): Define.
	(__AddResults): Likewise.
	(__ConvertToSQL): Likewise.
	(__AstToSQL): Likewise.
	(__AstToSQLHelper): Likewise.
	(__CheckTautology): Likewise.
	
2001-02-28  Alex Samuel  <samuel@codesourcery.com>

	Support attachments in the web UI.
	
	* qm/web.py (WebRequestHandler.__HandleScriptRequest): Handle
	results that aren't HTML.
	* qm/common.py (format_byte_count): New function.

	* qm/track/sql_idb.py (SqlIdb.__init__): Pass arguments to base
	class. 
	(SqlIdb.Close): New method.
	* qm/track/server.py (start_server): Add upload-attachment,
	submit-attachment, and download-attachment handlers.
	* qm/track/memory_idb.py (MemoryIdb.__init__): Pass arguments to
	base initializer.  Don't create directory.
	(MemoryIdb.Close): Call base-class Close.
	* qm/track/issue.py (Attachment.__init__): Add parameter defaults.
	(Attachment.__cmp__): New method.
	* qm/track/idb.py (IdbBase.__init__): Take more arugments.  Create
	the directory.  Set up attachments.
	(IdbBase.Close): New method.
	(IdbBase.GetNewAttachmentLocation): Likewise.
	(IdbBase.SetAttachmentData): Likewise.
	(IdbBase.GetAttachmentData): Likewise.
	(IdbBase.GetAttachmentSize): Likewise.
	(IdbBase.__GetAttachmentPath): Likewise.
	(get_field_type_description_for_query): Describe attachments.
	* qm/track/gadfly_idb.py (GadflyIdb.__init__): Pass arguments to
	base initializer.  Don't create directory.
	(GadflyIdb.Close): Call base-class Close.
	* qm/track/config.py (setup_idb_for_test): Add attachments field.
	* qm/track/cmdline.py (Command.__PerformInitialize): Fix exception.

	* qm/track/web/show.py (validate_mime_type): New function.
	(extract_attachment_field_value): Likewise.
	(decode_set_field_value): Likewise.
	(handle_submit): Process attachments and sets using above.  Don't
	add an identical revision.
	* qm/track/web/web.py (UploadAttachmentPageInfo): New class.
	(attachment_description_prefix): New variable.
	(attachment_mime_type_prefix): Likewise.
	(attachment_location_prefix): Likewise.
	(attachment_file_name_prefix): Likewise.
	(format_field_value): Handle attachments.
	(format_int_field_value): Handle form_encoded style.
	(format_text_field_value): Likewise.
	(format_set_field_value): Likewise.  Format brief and full
	differently.  Fill option values with form-encoded elements.
	Generate add function differently for different contained field
	types. 
	(format_enum_field_value): Handle form_encoded style.
	(format_attachment_field_value): New function.
	(handle_upload_attachment): Likewise.
	(handle_submit_attachment): Likewise.
	(handle_download_attachment): Likewise.
	(make_url_for_attachment): Likewise.
	* qm/track/web/templates/upload-attachment.dtml: New file.

2001-02-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/server.py (start_server): Bind the server.
	* qm/web.py (HTTPServer): New class.
	(WebServer): Derive from HTTPServer.
	(WebServer.GetXmlRpcUrl): Use GetServerAddress.
	(WebServer.Run): Don't bind here.
	(WebServer.Bind): New function.
	(WebServer.GetServerAddress): New method.

2001-02-27  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/cmdline.py (__Parse): Change formatting to happen from
	command options.

2001-02-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (get_host_name): Add fallback logic.

2001-02-26  Alex Samuel  <samuel@codesourcery.com>

	* README: Clarify --test-values flag.

	* qm/track/server.py (execute): Rearrange exception handling.
	* qm/track/issue_class.py (IssueFieldIid.SetDefaultValue): New method.
	* qm/track/config.py (initialize_idb): Check that the IDB path
	doesn't exist.
	
2001-02-25  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_url_button): New function.
	(PageInfo.MakeUrlButton): Call it.
	* qm/cmdline.py (CommandParser.BuildGetoptString): Don't add
	argument indicator if there's no short form.

	* qm/track/issue_class.py (default_categories): Add some bogus
	test values.
	(IssueField.Validate): Raise ValueError instead.
	(IssueFieldText): Add nonempty attribute.
	(IssueFieldText.Validate): Do validation.
	(IssueFieldAttachment.Validate): Raise ValueError.
	(IssueFieldEnumeration.__init__): Likewise.  Validate better.
	(IssueFieldIid.__init__): New method.
	(IssueFieldIid.Validate): Likewise.
	(IssueFieldUid.__init__): Likewise.
	(IssueClass.__init__): Make iid an IssueFieldIid.  Make summary
	nonempty.
	* qm/track/issue.py (Issue.__init__): Don't validate.
	(Issue.SetField): Likewise.
	(Issue.Validate): New function.
	(Issue.AssertValid): Likewise.
	(Issue.IsDeleted): Likewise.
	* qm/track/idb.py (get_field_type_description_for_query): Place
	enumerals in double quotes.
	* qm/track/config.py (setup_idb_for_test): Add problem_reports
	field. 
	* qm/track/memory_idb.py (MemoryIdb.AddIssue): Check issue
	validity.
	(MemoryIdb.AddRevision): Likewise.
	* qm/track/sql_idb.py (SqlIdb.AddIssue): Likewise.
	(SqlIdb.AddRevision): Likewise.

	* qm/track/web/web.py (format_field_value): Add name argument.
	(format_int_field_value): Likewise.
	(format_text_field_value): Likewise.  Adjust formatting.
	(format_set_field_value): Implement.
	(format_enum_field_value): Add name argument.  Change option
	values. 
	* qm/track/web/summary.py (SummaryPageInfo.IsIssueShown): Always
	return 1. 
	(handle_summary): Filter out deleted issues.
	* qm/track/web/show.py (ShowPageInfo.__init__): Add field_errors
	argument. 
	(handle_show): Make sure iid is specified.
	(handle_submit): Add is_new.  Issue error on revision
	incoherency.  Handle encoded set fields.  Validate submission and
	generate resubmission pages.
	* qm/track/web/stylesheets/qmtrack.css: Adjust.
	* qm/track/web/templates/show.dtml: Adjust formatting.  Use more
	styles.  Support field error messages.
	* qm/track/web/templates/query.dtml: Adjust table formatting.

2001-02-22  Alex Samuel  <samuel@codesourcery.com>

	* templates/dtml: Adjust.
	* qm/web.py (make_form_for_request): New function.
	* qm/track/sql_idb.py: Fix imports.
	(SqlIdb.__FilterCurrentRows): New function.
	(SqlIdb.GetIssues): Use it.
	* qm/track/issue_class.py: Fix imports.
	* qm/track/server.py (start_server): Add index and query pages.
	* qm/track/idb.py (IdbBase.Query): Use repr instead of quoting
	strings. 
	(get_field_type_description_for_query): New function.
	* qm/track/config.py (get_name): New function.
	(get_default_class): Likewise.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Add stuff to
	nav bar.
	(PageInfo.GetName): New method.
	(generate_error_page): New function.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Accept
	issues as argument.
	(handle_summary): Handle query arguments.
	* qm/track/web/show.py (handle_show): Use generate_error_page.
	* qm/track/web/index.py: New file.
	* qm/track/web/query.py: Likewise.
	* qm/track/web/templates/error.dtml: New file.
	* qm/track/web/templates/index.dtml: Likewise.
	* qm/track/web/templates/query.dtml: Likewise.

2001-02-21  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeUrlButton): New method.
	(PageInfo.MakeImageUrl): Likewise.
	(PageInfo.MakeSpacer): Likewise.
	(PageInfo.MakeRule): Likewise.

	* qm/track/sql_idb.py (SqlIdb.__BuildSqlForFieldValue): Call
	escape_for_sql. 
	(SqlIdb.__GetFieldFromRow): Call unescape_for_sql.
	(escape_for_sql): New function.
	(unescape_for_sql): Likewise.
	* qm/track/server.py (start_server): Register image path.
	(execute): Pass through KeyboardInterrupt.
	* qm/track/qmtrack.in: Handle KeyboardInterrupt.
	* qm/track/issue_class.py (IssueField.ValuesAreEqual): New method.
	* qm/track/issue.py (get_differing_fields): New function.
	* qm/track/gadfly_idb.py (GadflyCursor.execute): Flush log file.

	* qm/track/web/web.py (HistoryPageInfo): New class.
	(format_text_field_value): Fix brief output of multiline text.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Use
	GetIssues.
	* qm/track/web/show.py (ShowPageInfo.IsShowField): Show revision
	if it's not current.
	(ShowPageInfo.FormatFieldValue): Generate revision specially.
	(ShowPageInfo.MakeEditUrl): Adjust url.
	(ShowPageInfo.MakeHistoryUrl): Likewise.
	(ShowPageInfo.MakeShowRevisionUrl): New method.
	(ShowPageInfo.FormatHistory): Likewise.
	(handle_show): Set up extra stuff for history or past revisions.
	(handle_new): Fix typo.
	* qm/track/web/templates/show.dtml: Adjust formatting for history.
	* qm/track/web/templates/history.dtml: New file.

	* qm/track/web/images: New directory.
	* qm/track/web/images/clear.gif: New file.

2001-02-20  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (UserError): New class.
	(get_host_name): Use gethostbyname_ex.
	* qm/cmdline.py (CommandError): Derive from UserError.

	* qm/track/sql_idb.py (SqlIdb.GetIssues): New method.
	(SqlIdb.Query): Remove.
	(SqlIdb.GetIssue): Allow none where clause.
	* qm/track/server.py (execute): Catch UserError instead of
	RuntimeError.
	* qm/track/memory_idb.py (MemoryIdb.AddIssueClass): Raise KeyError
	on duplicate.
	(MemoryIdb.GetIssues): Support retrieval of all issues in a single
	class.
	* qm/track/gadfly_idb.py (GadflyIdb.__init__): Don't lock.
	(GadflyIdb.__del__): Rename to...
	(GadflyIdb.Close): ... this.  Don't unlock.
	* qm/track/config.py (open_idb): Fix typo in exception code.

2001-02-20  Alex Samuel  <samuel@codesourcery.com>

	* templates/py: Set emacs fill-column.
	
	* Makefile.in (SUBDIRS): Remove doc.  Add sgmlop.
	(setup): Add sgmlop/Makefile.
	(sgmlop/Makefile): New rule.
	* README: Add third-party software list.
	* standard.mk.in (all): Remove doc.
	
	* qm/web.py (WebRequestHandler.__ProcessRequest): Rename to...
	(WebRequestHandler.__HandleRequest): ... this.
	(WebRequestHandler.__HandleScriptRequest): New method.
	(WebRequestHandler.__HandleXmlRpcRequest): Likewise.
	(WebRequestHandler.__HandleFileRequest): Likewise.
	(WebServer.__init__): Initialize XML-RPC.  Set port and log file here. 
	(WebServer.GetXmlRpcUrl): New method.
	(WebServer.IsXmlRpcUrl): Likewise.
	(WebServer.Run): Don't set port and log file here.
	* qm/setup_path.py.in: Add sgmlop and xmlrpc to path.
	* qm/common.py (format_exception): New function.

	* qm/track/qmtrack.in (script_name): Remove.  Set state variable
	instead.
	(exit_code): New variable.
	Handle exceptions differently.
	* qm/track/server.py (do_command_for_xml_rpc): New function.
	(start_server): Enable XML-RPC.  Write XML-RPC URL to URL file.
	(execute): Handle error messages and exit code.  Implement remote
	mode. Handle exceptions.
	* qm/track/config.py (open_idb): Set server_url state in remote mode.
	(close_idb): Clean up correspondingly.
	* qm/track/cmdline.py (Command.GetArgumentList): New function.
	* qm/track/web/summary.py (SummaryPageInfo.IsShowIssue): Rename to...
	(SummaryPageInfo.IsIssueShown): ... this.
	* qm/track/web/templates/summary.dtml: Adjust accordingly

2001-02-18  Alex Samuel  <samuel@codesourcery.com>

	* README: Add more instructions.
	* qm/common.py (label_regex): Rename to...
	(__label_regex): ... this.
	(label_thunk_regex): Rename to...
	(__label_thunk_regex): ... this.
	(__host_name): New variable.
	(get_host_name): New function.
	* qm/track/config.py (open): Rename to...
	(open_idb): ... this.  Catch only IOError.
	(close): Rename to...
	(close_idb): ... this.
	(initialize): Rename to...
	(initialize_idb): ... this.
	* qm/track/cmdline.py: Adjust accordingly.
	* qm/track/qmtrack.in: Likewise.
	* qm/track/server.py (start_server): Write URL file.
	(execute): Fix typo.

2001-02-18  Alex Samuel  <samuel@codesourcery.com>

	* Makefile.in (SUBDIRS): Add qm.
	(README): Update.
	* configure.in (AC_OUTPUT): Add qm/Makefile.
	* configure: Regenerate.	
	* standard.mk.in (PYTHONBIN): New macro.
	(PYTHON): Use it.

	* qm/Makefile.in: New file.
	* qm/command_line.py: Rename to...
	* qm/cmdline.py: ... this, with heavy modifications.
	* qm/common.py (FileSystemMutex.MutexLockError): Remove.
	(FileSystemMutex.Lock): Make sure parnet directory exists.
	(FileSystemMutex.IsLocked): New method.
	(Configuration): New class.
	(base_directory): New variable.
	(get_base_directory): New function.
	* qm/setup_path.py.in: New file.
	* qm/web.py: Likewise.

	* qm/track/qmtrack.in: New file.
	* qm/track/__init__.py: Update imports.
	* qm/track/qmtrack.py: Rename to...
	* qm/track/cmdline.py: ... this, with heavy modifications.
	* qm/track/config.py: New file.
	* qm/track/idb.py: Clean up imports and comments.
	(IdbBase.PerformQuery): Rename to...
	(IdbBase.Query): ... this.  Adjust.
	(get_ib_class): New function.
	* qm/track/issue.py (Issue.__init__): Don't object to missing
	field values. 
	(Issue.StampTime): New method.
	(IssueSortPredicate): New class.
	* qm/track/issue_class.py (IssueField.__init__): Initialize more
	attributes. 
	(IssueField.IsAttribute): New method.
	(IssueFieldText): Rename multiline attribute to structured.
	(IssueFieldEnumeration.Validate): Try int conversion.
	(IssueFieldEnumeration.GetEnumerals): New method.
	(IssueFieldEnumeration.ValueToName): Likewise.
	(IssueClass.__init__): Adjust mandatory fields.
	(IssueClass): Redefine __fields attribute and add
	__fields_by_name.  Use throughout.
	* qm/track/memory_idb.py (MemoryIdb.__init__): Don't lock.
	(MemoryIdb.__del__): Rename to...
	(MemoryIdb.Close): ... this.
	(MemoryIdb.AddIssue): Stamp time.
	(MemoryIdb.AddRevision): Likewise.
	(MemoryIdb.GetIids): New method.
	(MemoryIdb.GetIssues): Return copies of current revisions only.
	(MemoryIdb.GetAllRevisions): Return copies.
	(MemoryIdb.Query): Remove.
	* qm/track/server.py: New file.
	* qm/track/sql_idb.py (SqlIdb.AddIssue): Stamp time.
	(SqlIdb.AddRevision): Likewise.

	* qm/track/web: New directory.
	* qm/track/web/__init__.py: New file.
	* qm/track/web/show.py: Likewise.
	* qm/track/web/summary.py: Likewise.
	* qm/track/web/web.py: Likewise.
	* qm/track/web/stylesheets: New directory.
	* qm/track/web/stylesheets/qmtrack.css: New file.
	* qm/track/web/templates: New directory.
	* qm/track/web/templates/show.dtml: New file.
	* qm/track/web/templates/summary.dtml: Likewise.

	* templates/dtml: New file.
	
2001-02-16  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/command_line.py: Fix formatting issue.
	* qm/track/qmtrack.py: Likewise. Fix bug to catch exception when
	Validate fails on a SetField.

2001-02-16  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/command_line.py: Fix coding standards issues.
	* qm/track/idb.py (IdbBase::PerformQuery): Define.
	* qm/track/qmtrack.py: Fix split up strings to use 'printf' syntax.
	(CommandLine::PerformQuery): Move code into idb.py. Only do UI stuff.
	
2001-02-15  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/qmtrack.py: Fix coding standards issues.
	* qm/track/issue_class.py: Likewise.
	* qm/track/memory_idb.py: Likewise.

	* qm/command_line.py (CommandParser::ParseCommandLine): Fix
	to use 'write' instead of print. Add code to check for command
	existence.
	
2001-02-14  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/issue_class.py (IssueFieldEnumeration::GetEnumeration): 
	Define.
	(IssueClass::__init__): Make 'iid' have no default value.

	* qm/track/memory_idb.py (MemoryIdb::GetIssues): Define.

	* qm/track/qmtrack.py (CommandLine::__init__): Initialize 
	results.
	(CommandLine::ParseFieldValuePairs): Handle no '=' in string.
	(CommandLine::OpenDatabase): Change warning to error.
	(CommandLine::PerformCreate): Fix bugs and do type checking on
	fields. Do mandatory fields correctly.
	(CommandLine::CheckFieldTypes): Define.
	(CommandLine::PerformEdit): Fix bugs and do type checking on
	fields.
	(CommandLine::PerformQuery): Define.
	
2001-02-12  Benjamin Chelf  <chelf@codesourcery.com>

        * qm/track/qmtrack.py (__main__): Change to catch exception.
	* qm/command_line.py (ErrorHandler): Change to raise exception.
	
	* qm/track/qmtrack.py (PrintResults): Change from 'print' to
	write.

2001-02-11  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/command_line.py (ErrorHandler): New method.
	(__init): Add output parameter.
	(ParseCommandLine): Fix bugs.
	
	* qm/track/qmtrack.py: New file.

2001-02-08  Alex Samuel  <samuel@codesourcery.com>

	Module zope-dtml is now part of this module.  Add configury to set
	up and use it.
	
	* configure.in (/usr/lib/python1.5/config/Makefile.pre.in): Check file.
	* configure: Regenerate.
	* Makefile.in (SUBDIRS): Add zope-dtml/ExtensionClass.
	(setup): Add zope-dtml/ExtensionClass/Makefile.
	(zope-dtml/ExtensionClass/Makefile): New rule.
	* standard.mk.in (PYTHON): Build PYTHONPATH.
	(PYTHONDIRS): New variable.

2001-01-09  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/command_line.py: New file.

	* qm/test.py (test_parser_create): Define.
	(test_paresr_parse): Likewise.
	(test_parser_help): Likewise.
	(test_parser_duplicate_long): Likewise.
	(test_parser_duplicate_short): Likewise.
	(test_parser_two_char_short): Likewise.
	(test_parser_no_long): Likewise.
	(test_parser_dup_command_short): Likewise.
	(test_parser_dup_command_long): Likewise.
	(regession_tests): Add above tests.

2001-01-09  Alex Samuel  <samuel@codesourcery.com>

	* Makefile.in (PYTHONDOCDIRS): New variable.
	* standard.mk.in (doc-python): Build for PYTHONDOCDIRS only.

2001-01-09  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Clarify naming conventions.
	* templates/py: Add section banners.
	
	* configure.in: New file.
	* install-sh: Likewise.
	* configure: Likewise.
	* standard.mk.in: New file.
	* standard.mk: Remove.
	* Makefile.in: New file.
	* Makefile: Remove.
	* doc/Makefile.in: New file.
	* doc/Makefile: Remove.
	* doc/design/qmconfig/Makefile.in: New file.
	* doc/design/qmconfig/Makefile: Remove.
	* doc/design/qmtest/Makefile.in: New file.
	* doc/design/qmtest/Makefile: Remove.
	* doc/design/qmtrack/Makefile.in: New file.
	* doc/design/qmtrack/Makefile: Remove.
	
2001-01-09  Alex Samuel  <samuel@codesourcery.com>

	* README: New file.

2001-01-08  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (BUILDDIR): New macro.
	(DOCDIR): Likewise.
	(HAPPYDOC): Likewise.
	(doc): Depend on doc-python.
	(doc-python): New rule.

2001-01-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/__init__.py: Import idb.
	* qm/track/idb.py: New file.
	* qm/track/sql_idb.py (SqlIdb): Drive from IdbBase.
	(SqlIdb.__init__): Initialize base class.
	(SqlIdb.AddIssue): Process triggers.  Return result code.
	(SqlIdb.AddRevision): Likewise.
	(SqlIdb.GetIssue): Process triggers.
	(SqlIdb.GetAllRevisions): Likewise.
	(SqlIdb.RegisterTrigger): Remove.
	(SqlIdb.UnregisterTrigger): Likewise.
	(SqlIdb.GetTriggers): Likewise.
	(SqlIdb.__InsertIssue): New method.
	* qm/track/gadfly_idb.py (GadflyIdb.__init__): Initialize base class.
	* qm/track/memory_idb.py (MemoryIdb): Derive from IdbBase.
	(MemoryIdb.__init__): Initialize base class.
	(MemoryIdb.AddIssue): Process triggers.  Return result code.
	(MemoryIdb.AddRevision): Likewise.
	(MemoryIdb.GetIssue): Process triggers.
	(MemoryIdb.GetAllRevisions): Likewise.
	(MemoryIdb.RegisterTrigger): Remove.
	(MemoryIdb.UnregisterTrigger): Likewise.
	(MemoryIdb.GetTriggers): Likewise.
	(MemoryIdb.__InsertIssue): New method.
	* qm/track/test.py (TestPreupdateTrigger): New class.
	(test_preupdate_trigger): New test.
	(TestGetTrigger): New class.
	(test_get_trigger): New test.
	(TestPostupdateTrigger): New class.
	(test_postupdate_trigger): New test.
	(regression_tests): Add new tests.
	Run memory IDB tests first.

2001-01-04  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (MutexLockError): New class.
	(FileSystemMutex): Likewise.
	* qm/regression_test.py (run_regression_test_driver): Don't exit.
	* qm/test.py: New file.
	
	* qm/track/issue.py (Issue.__init__): Adjust for changes in
	IssueClass. 
	(Issue.Copy): New function.
	(Attachment): New class.
	* qm/track/issue_class.py (default_categories): New variable.
	(default_states): Likewise.
	(IssueField.__init__): Handle default values differently.
	(IssueField.GetDefaultValue): Likewise.
	(IssueField.SetDefaultValue): New function.
	(IssueField.UnsetDefaultValue): Likewise.
	(IssueField.HasDefaultValue): Likewise.
	(IssueFieldInteger.__init__): Set default value.
	(IssueFieldText.__init__): Likewise.
	(IssueFieldSet.__init__): Likewise.
	(IssueFieldAttachment.__init__): Likewise.
	(IssueFieldEnumeration.__init__): Likewise.
	(IssueFieldTime.__init__): Likewise.
	(IssueFieldUid.__init__): Likewise.
	(IssueClass.__init__): Create mandatory fields.
	(IssueClass.GetFields): Store fields as a map.
	(IssueClass.HasField): New function.
	* qm/track/gadfly_idb.py: New file.
	* qm/track/sql_idb.py: Likewise.
	* qm/track/memory_idb.py: Likewise.
	* qm/track/test.py: Adjust for new field initializers throughout.
	(test_create_idb): New test.
	(test_add_issue_class): Likewise.
	(test_add_issues): Likewise.
	(test_get_issues): Likewise.
	(test_attachments): Likewise.
	
2001-01-04  Alex Samuel  <samuel@codesourcery.com>

	* gadfly/__init__.py: New file.

	* templates/Makefile: Update year.
	* templates/docbook: Likewise.
	* templates/docbook-chapter: Likewise.
	* templates/html: Likewise.
	* templates/py: Likewise.
	* templates/xml: Likewise.

2000-12-22  Alex Samuel  <samuel@codesourcery.com>

	* gadfly/.cvsignore: New file.
	
2000-12-28  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/design-td.xml: Added new sections and
	details.
	
	* doc/design/qmconfig/design-lm.xml: Break into sections.
	* doc/design/qmconfig/design-probe.xml: Likewise.
	* doc/design/qmconfig/design-td.xml: Likewise.

2000-12-27  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/biblio.xml: Add an id.

	* doc/design/qmconfig/design-pdd.xml: New file.
	* doc/design/qmconfig/design-basic.xml: New file.

	* doc/design/qmconfig/figures/pkg_qmconfig.*: Re-scale.
	* doc/design/qmconfig/design.xml: Add format="PNG" to imagedata's.
	* doc/design/qmconfig/design-lm.xml: Likewise.
	* doc/design/qmconfig/design-probe.xml: Likewise.
	* doc/design/qmconfig/design-td.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.

2000-12-26  R. Lindsay Todd  <toddr@rpi.edu>
	
	* standard.mk: Run pdfjadetex thrice, to get all references correct.

	* doc/design/qmconfig/design-probe.xml: Updated API for probe
	class, to be consistent with other components.
	* doc/design/qmconfig/figures/cl_probe.*: Updated to match API for
	probe class.

	* doc/design/qmconfig/design-lm.xml: Add figure for LangServ.
	* doc/design/qmconfig/figures/cl_langserv.*: New file.

2000-12-22  Alex Samuel  <samuel@codesourcery.com>

	* Makefile (setup): New target.
	(gadfly/sqlwhere.py): Likewise.
	* standard.mk (setup): New phony target.
	
2000-12-22  Alex Samuel  <samuel@codesourcery.com>

	* Makefile: New file.

2000-12-21  Alex Samuel  <samuel@codesourcery.com>

	* qm/.cvsignore: New file.
	* qm/track/.cvsignore: Likewise.
	
2000-12-21  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (PRINTTEX): Define as dummy if there's no DocBook.
	(PRINTPDF): Likewise.
	(test): New target.

	* qm/__init__.py: New file.
	* qm/common.py: Likewise.
	* qm/regression_test.py: Likewise.
	* qm/track/__init__.py: Likewise.
	* qm/track/issue.py: Likewise.
	* qm/track/issue_class.py: Likewise.
	* qm/track/test.py: Likewise.
	
2000-12-15  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/design.xml: Reorder some sections.
	* doc/design/qmconfig/design-lm.xml: Add additional ids.
	* doc/design/qmconfig/design-td.xml: Likewise.
	* doc/design/qmconfig/design-probe.xml: Likewise.  Added rough
	draft of probe database.

2000-12-15  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/overview.xml: Remove /> sequences, so as to
	not confuse psgml.
	* doc/design/qmconfig/design-lm.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.
	* doc/design/qmconfig/design.xml: Likewise.
	* doc/design/qmconfig/design-td.xml: Likewise.

2000-12-15  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/design.xml: Add/fix id's.
	* doc/design/qmconfig/intro.xml: Likewise.
	* doc/design/qmconfig/overview.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.
	* doc/design/qmconfig/design-td.xml: Likewise.  Fix images.
	* doc/design/qmconfig/qmconfig.xml: Add qm.mod.

2000-12-14  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(PRINTDIR)/$(PRINTPDF)): Return true even if empty
	$(DOCBITMAPS).

2000-12-14  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(PRINTDIR)/$(PRINTPDF)): Handle empty $(DOCBITMAPS).

2000-12-14  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Update ChangeLog and documentation instructions. 

2000-12-13  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(PRINTDIR)/$(PRINTPDF)): Copy bitmaps into print
	dir instead of setting paths. 
	* doc/design/qmconfig/design-probe.xml: Scale images.
	* doc/design/qmconfig/design-td.xml: Likewise.
	* doc/design/qmconfig/design.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.

2000-12-13  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(HTMLMANIFEST)): Put graphics filename in manifest
	only.
	* doc/design/qmconfig/design-probe.xml: Adjust image filenames.
	* doc/design/qmconfig/design-td.xml: Likewise.
	* doc/design/qmconfig/design.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.

2000-12-13  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(PRINTDIR)/$(PRINTPDF)): Set TEXINPUTS.
	* doc/design/qmconfig/Makefile (DOCBITMAPS): Set it.
	* doc/design/qmtext/iface.xml: Always require qmtest subcommand.

2000-12-13  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtest/iface.xml: Twiddle command-line syntax.

	* doc/design/qmtest/core.xml: Regularize entity ids.
	* doc/design/qmtest/impl.xml: Likewise.
	* doc/design/qmtest/qmtest.xml: Likewise.
	* doc/design/qmtest/req.xml: Likewise.

2000-12-07  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (gui): New entity.
	(url): Likewise.
	* doc/design/qmtrack/concepts.xml: Fix typos.
	* doc/design/qmtrack/implementation.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Likewise.
	* doc/design/qmtrack/requirements.xml: Likewise.
	* doc/design/qmtrack/triggers.xml: Likewise.
	* doc/design/qmtrack/user-interface.xml: Likewise.
	* doc/design/qmtrack/xml-repr.xml: Likewise.
	
2000-12-07  Alex Samuel  <samuel@codesourcery.com>

	Tag "version-0-2" for delivery to LANL.
	
	* standard.mk ($(HTMLINDEX)): Process graphics here.
	($(HTMLMANIFEST)): Remove separate target.
	
	* doc/qm-html.dsl (%generate-legalnotice-link%): Define true.
	* doc/qm-print.dsl (%chapter-autolabel%): Likewise.
	(%section-autolabel%): Likewise.
	* doc/qm-opl.xml: New file.
	* doc/qm.mod (qmbuild): Use <application> element.
	(qmconfig): Likewise.
	(qmtest): Likewise.
	(qmtrack): Likewise.
	(html): New entity.
	(mime): Likewise.
	(dashdash): Likewise.
	(qmlicense): Likewise.

	* doc/design/qmtest/core.xml: Edit for style, spelling,
	consistency, and markup.
	* doc/design/qmtest/iface.xml: Likewise.
	* doc/design/qmtest/impl.xml: Likewise.
	* doc/design/qmtest/qmtest.xml: Likewise.
	* doc/design/qmtest/refs.xml: Likewise.
	* doc/design/qmtest/req.xml: Likewise.
	
	* doc/design/qmtrack/concepts.xml: Likewise.
	* doc/design/qmtrack/implementation.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Likewise.
	* doc/design/qmtrack/qmtrack.xml: Likewise.
	* doc/design/qmtrack/requirements.xml: Likewise.
	* doc/design/qmtrack/triggers.xml: Likewise.
	* doc/design/qmtrack/user-interface.xml: Likewise.
	* doc/design/qmtrack/xml-repr.xml: Likewise.
	
2000-12-06  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (idb): Remove entity.
	(iid): Likewise.
	(faq): New entity.
	
	* doc/design/qmtest/refs.xml: Strip linefeeds.

	* doc/design/qmtrack/qmtrack.xml (idb): New entity.
	(iid): Likewise.
	(uid): Likewise.
	* doc/design/qmtrack/concepts.xml: Edit.
	* doc/design/qmtrack/implementation.xml: Likewise.
	* doc/design/qmtrack/triggers.xml: Likewise.
	* doc/design/qmtrack/user-interface.xml: Likewise.
	* doc/design/qmtrack/xml-repr.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Incorporate new text.
	* doc/design/qmtrack/requirements.xml: Likewise.
	* doc/design/qmtrack/references.xml: New file.
	* doc/design/qmtrack/state-model-example.dia: Likewise.
	* doc/design/qmtrack/state-model-example.png: Likewise.
	
2000-12-06  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/create1.html: New file.
	* doc/design/qmtrack/create2.html: Likewise.
	* doc/design/qmtrack/edit1.html: Likewise.
	* doc/design/qmtrack/edit2.html: Likewise.
	* doc/design/qmtrack/query1.html: Likewise.
	* doc/design/qmtrack/query2.html: Likewise.
	* doc/design/qmtrack/main1.html: Likewise.

	* doc/design/qmtrack/create1.jpg: Update.
	* doc/design/qmtrack/create2.jpg: Likewise.
	* doc/design/qmtrack/edit1.jpg: Likewise.
	* doc/design/qmtrack/edit2.jpg: Likewise.
	* doc/design/qmtrack/query1.jpg: Likewise.
	* doc/design/qmtrack/query2.jpg: Likewise.
	* doc/design/qmtrack/query3.jpg: Likewise.
        * doc/design/qmtrack/main1.jpg: New file.

	* doc/design/user-interface.xml: Update e-mail section by adding
	headers. Flesh out web section.
	
2000-12-05  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml (idb-impl.xml): Remove entity.
	* doc/design/qmtrack/idb-impl.xml: Remove.
	* doc/design/qmtrack/implementation.xml: Describe SQL IDB.
	* doc/design/qmtrack/xml-repr.xml: Tune.
	
2000-12-05  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/user-interface.xml: Tidy up formatting.

2000-12-05  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/user-interface.xml: Fix inconsistencies with
	other sections.
	* doc/design/qmtrack/create1.jpg: Update.
	* doc/design/qmtrack/edit1.jpg: Likewise.
	* doc/design/qmtrack/edit2.jpg: Likewise.
	* doc/design/qmtrack/query1.jpg: Likewise.
	* doc/design/qmtrack/query2.jpg: Likewise.
	* doc/design/qmtrack/query3.jpg: Likewise.

2000-12-05  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/design-td.xml: New file

2000-12-05  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/Makefile (DOCBITMAPS): Add *.png.
	* doc/design/qmtrack/web-gui-states.dia: New file.
	* doc/design/qmtrack/web-gui-states.png: Likewise.
	* doc/design/qmtrack/concepts.xml: Add categories section.
	* doc/design/qmtrack/idb-impl.xml: Edit.
	* doc/design/qmtrack/triggers.xml: Explain get triggers better.
	* doc/design/qmtrack/user-interface.xml: Expand.
	
2000-12-04  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod: New file.
	* doc/design/qmtest/qmtest.xml: Don't declare phrase entities.
	Incorporate qm.mod.
	* doc/design/qmtrack/qmtrack.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Add link.
	* doc/design/qmtrack/user-interface.xml: Fix entity.  Fix ulink.
	* doc/design/qmtrack/xml-repr.xml: Improve example.

2000-12-04  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/concepts.xml: Edit.  Add ids.
	* doc/design/qmtrack/idb-impl.xml: Likewise.
	* doc/design/qmtrack/implementation.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Likewise.
	* doc/design/qmtrack/requirements.xml: Likewise.
	* doc/design/qmtrack/xml-impl.xml: Likewise.
	
2000-12-04  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (HTMLINDEX): New macro.
	(PRINTDIR): Likewise.
	(PRINTTEX): Likewise.
	(PRINTPDF): Likewise.
	(html-dir): Remove target.
	(html-output): Likewise.
	(html-graphics): Likewise.
	($(HTMLINDEX)): New target.
	($(HTMLMANIFEST)): Likewise.
	($(HTMLTARBALL)): Change dependencies.
	(docbook-print): Remove target.
	($(PRINTTEX)): New target.
	($(PRINTPDF)): Likewise.
	(%.html): Likewise.
	
	* doc/design/qmtrack/qmtrack.xml (dtml): New entity.
	(implementation.xml): Likewise.
	(idb-api.xml): Remove entity.
	Add authors.
	* doc/design/qmtrack/concepts.xml: Include triggers and
	user interface sections.
	* doc/design/qmtrack/idb-api.xml: Rename to...
	* doc/design/qmtrack/implementation.xml: ... this.  Add trigger
	API.  Include IDB implementation section.
	* doc/design/qmtrack/idb-impl.xml: Make it a section.
	* doc/design/qmtrack/triggers.xml: Remove API stuff.  Make it a
	section. 
	* doc/design/qmtrack/user-interface.xml: Make it a section.
	Reformat. 
	
2000-12-02  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/user-interface.xml: Update e-mail section.

2000-12-01  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk: Update instructional comments.
	(HTMLDIR): New macro.
	(HTMLMANIFEST): Likewise.
	(HTMLTARBALL): Likewise.
	(docbook-html): Make it a collection target only.
	(html-dir): New target.
	(html-output): Likewise.
	(html-graphics): Likewise.
	($(HTMLTARBALL)): Likewise.
	(docbook-print): Process TeX output for PDF.

	* doc/design/qmtest/iface.xml: Add ids.  Clean up markup and
	identation. 
	* doc/design/qmtest/qmtest.xml (prompt): New entity.
	* doc/design/qmtest/req.xml: Remove bogus tag.

	* doc/design/qmtrack/Makefile (DOCBITMAPS): New macro.
	* doc/design/qmtrack/user-interface.xml: Add ids.

2000-12-01  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/concepts.xml: Add ids.  Rearrange sections.
	* doc/design/qmtrack/idb-api.xml: Remove queries section.
	* doc/design/qmtrack/idb-impl.xml: Fix link.
	* doc/design/qmtrack/introduction.xml: Don't include requirements.xml. 
	* doc/design/qmtrack/qmtrack.xml (prompt): New entity.
	(qmtrack-cmd): Likewise.
	Don't include xml-repr.xml.  Include requirements.xml.
	* doc/design/qmtrack/requirements.xml: Make it a chapter.
	* doc/design/qmtrack/user-interface.xml: Edit command-line
	section.  Tidy formatting.
	* doc/design/qmtrack/xml-repr.xml: Make it a section.
	
2000-11-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml: Don't include user-api.xml.
	* doc/design/qmtrack/user-api.xml: Remove.
	
2000-11-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm-html.dsl (html-manifest): Set true.
	(html-manifest-filename): Set to "docbook-html.manifest".
	(%use-id-as-filename%): Set to true.
	
	* doc/design/qmtrack/qmtrack.xml (api): New entity.
	(sc): Likewise.
	(introduction.xml): Likewise.
	Include introduction.
	* doc/design/qmtrack/introduction.xml: New file.
	* doc/design/qmtrack/requirements.xml: Make it a section.  Edit.
	* doc/design/qmtrack/concepts.xml: Revise introductory text.
	Add ids.  Rename time field.  
	
2000-11-30  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/desgin/qmtrack/create1.jpg: New file.
	* doc/desgin/qmtrack/create2.jpg: Likewise.
	* doc/desgin/qmtrack/edit1.jpg: Likewise.
	* doc/desgin/qmtrack/edit2.jpg: Likewise.
	* doc/desgin/qmtrack/edit3.jpg: Likewise.
	* doc/desgin/qmtrack/query1.jpg: Likewise.
	* doc/desgin/qmtrack/query2.jpg: Likewise.
	* doc/desgin/qmtrack/query3.jpg: Likewise.	
	
	* doc/design/qmtrack/user-interface.xml: Update to contain new
	ideas for interfaces.

2000-11-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/concepts.xml: Rename mandatory fields.
	Rewrite queries section.
	* doc/design/qmtrack/idb-api.xml: Edit.
	* doc/design/qmtrack/idb-impl.xml: New file.
	* doc/design/qmtrack/qmtrack.xml: Include idb-impl.xml.
	* doc/design/qmtrack/xml-repr.xml: Add ids and links.
	
2000-11-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm-html.dsl (%section-autolabel%): Set to true.
	(chunk-skip-first-element-list): Set to empty list.

2000-11-29  Mark Mitchell  <mark@codesourcery.com>

	* doc/design/qmtest/qmtest.xml: Revise heavily, tightening
	prose, clarifying concepts, etc.
	* doc/design/qmtest/core.xml: Likewise.
	* doc/design/qmtest/impl.xml: Likewise.
	* doc/design/qmtest/req.xml: Likewise.

2000-11-29  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml: Make acronyms upper-case.
	(dtd): New entity.
	(xml): Likewise.
	Include xml-repr.xml.
	* doc/design/qmtrack/triggers.xml: Finish.
	* doc/design/qmtrack/xml-repr.xml: New file.
	* doc/design/qmtrack/user-interface.xml: Add id's.  Fix some
	indentation. 
	
2000-11-28  Mark Mitchell  <mark@codesourcery.com>

	* doc/design/qmtest/core.xml: Fix DocBook syntax errors.
	* doc/design/qmtest/impl.xml: Likewise.
	* doc/design/qmtest/qmtest.xml: Likewise.
	* doc/design/qmtest/refs.xml: Likewise.
	* doc/design/qmtest/req.xml: Likewise.
	* doc/design/qmtest/design.html: Remove.

2000-11-28  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/triggers.xml: New file.

2000-11-27  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml: Add user-interface.xml.
	* doc/design/qmtrack/user-api.xml: Fix typos.
	* doc/design/qmtrack/user-interface.xml: New file.

2000-11-26  Alex Samuel  <samuel@codesourcery.com>
	
	* doc/design/qmtrack/idb-api.xml: Add missing </section> tag.
	
2000-11-26  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/concepts.xml: Continue.
	* doc/design/qmtrack/idb-api.xml: Likewise.

2000-11-25  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/user-api.xml: Make style changes. Update
	based on conversations with Alex.

2000-11-20  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtest/req.xml: New file.

2000-11-20  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Add discussion of doc strings.

2000-11-20  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml: Added user-api.xml.
	* doc/design/qmtrack/user-api.xml: New file.

2000-11-16  Alex Samuel  <samuel@codesourcery.com>

	* doc/concept: New directory.
	* doc/concept/sapcat: Likewise.
	* doc/design/qmconfig/*: Surgically move all repository files to...
	* doc/concept/sapcat/*: ... here.

2000-11-10  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (docbook-html): Fix files to tidy.

2000-11-10  Alex Samuel  <samuel@codesourcery.com>

	Conversion to DocBook.
	
	* standard.mk (TIDYFLAGS): Use one-space indent.
	(JADE): New variable.
	(JADEEXTRA): Likewise.
	(SGMLDIRS): Likewise.
	(HTMLSS): Likewise.
	(PRINTSS): Likewise.
	(NULLSTIRNG): Likewise.
	(SPACE): Likewise.
	(doc): New rule.
	(doc-html): New rule, conditionally.
	(doc-print): Likewise.
	(docbook-html): New rule.
	(docbook-print): Likewise.
	* doc/GNUmakefile: Rename to...
	* doc/Makefile: ... this.
	
	* doc/qm-print.dsl: New file.
	* doc/qm-html.dsl: Likewise.
	
	* doc/design/qmtest/GNUmakefile: Rename to...
	* doc/design/qmtest/Makefile: ... this.
	* doc/design/qmtest/*.xhtml: Remove.
	* doc/design/qmtest/*.xml: New files.

	* doc/design/qmtrack/GNUmakefile: Rename to...
	* doc/design/qmtrack/Makefile: ... this.
	* doc/design/qmtrack/*.xhtml: Remove.
	* doc/design/qmtrack/*.xml: New files.

	* templates/docbook: New file.
	* templates/docbook-chapter: Likewise.
	* templates/xml: Add XML PI.
	
2000-11-06  Alex Samuel  <samuel@codesourcery.com>

	* doc/GNUmakefile (SUBDIRS): Add design/qmtest.

2000-11-06  Alex Samuel  <samuel@codesourcery.com>

	* doc/process-xhtml.py: Handle multiple term classes.  Use
	pickling for .terms file.
	(terms_classes): New list.
	(terms_def_classes): Likewise.
	* templates/html: Add emacs gunk to set fill-column.
	
2000-11-03  Alex Samuel  <samuel@codesourcery.com>

	* doc/process-xhtml.py (clean_up_term): New function.
	Use it.  Try to handle pluralized terms.
	* doc/qm.css (div.XML): New class.
	(span.Function): Likewise.
	
2000-11-01  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.css (a.Dfn): Remove.
	(a.TermDef): Fix background-color.
	(span.Identifier): Recreate.
	(span.Class): Likewise.
	(table): New style.
	(tr.Heading): New class.
	(span.Fixme): Likewise.

	* templates/html: Add Emacs local variables.

2000-10-31  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (%.html): Fix.
	* doc/process-xhtml.py: Fix href attribute.
	* doc/qm.css (a.TermDef): Fix font-style.
	(div.api): Rename to...
	(div.API): ... this.
	(span.Identifier): New class.
	(span.Class): Likewise.
	
	* doc/design/qmtest/terms.xhtml: New file.
	
2000-10-27  Alex Samuel  <samuel@codesourcery.com>

	* templates/html: Use Open Publication License.
	* doc/design/qmtest/design.html: Likewise.
	* doc/design/qmtrack/index.xhtml: Likewise.
	* doc/design/qmtrack/architecture.xhtml: Likewise.
	* doc/design/qmtrack/requirements.xhtml: Likewise.
	
2000-10-26  Alex Samuel  <samuel@codesourcery.com>

	* doc/process-xhtml.py: Convert to coding standards.
	* doc/qm.css (div.api): New style.
	* templates/html: Remove emacs variable stuff.
	* templates/py: Add emacs variable stuff.
	
2000-10-25  Alex Samuel  <samuel@codesourcery.com>

	* stanard.mk: Add comments.
	(.PHONY): Fix typo.
	(TOPDIR): New variable.
	(XHTMLPROCESS): Likewise.
	($(SUBDIRS)): Pass TOPDIR to child make processes.
	(%.html): Use XHTML processor script.
	* doc/process-xhtml.py: New script.
	* doc/design/qmtrack/GNUmakefile: Use TOPDIR.
	
	* doc/qm.css: Improve comments.
	
2000-10-25  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk: New file.
	* doc/GNUmakefile: Likewise.
	* doc/qm.css: Likewise.
	* doc/design/qmtrack/GNUmakefile: Likewise.
	* templates/html: Update for XHTML.
	
2000-10-24  Alex Samuel  <samuel@codesourcery.com>

	* templates/html (DOCTYPE): Add.

2000-10-24  Alex Samuel  <samuel@codesourcery.com>

	* templates/py: New file.

2000-10-24  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmconfig/...: Import.

2000-10-22  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtest/design.html: Import.
	
2000-10-22  Alex Samuel  <samuel@codesourcery.com>

	* doc/design: New directory.
	* doc/design/qmconfig: Likewise.
	* doc/design/qmbuild: Likewise.
	* doc/design/qmtest: Likewise.
	* doc/design/qmtrack: Likewise.
	
2000-10-22  Alex Samuel  <samuel@codesourcery.com>

	* ChangeLog: New file.
	* README.sources: Likewise.
	* COPYING: Likewise.
	
	* templates: New directory.
	* doc: Likewise.
