dslinux/user/pixil/pixilDT/src AddressBook.cpp AddressBook.h AddressBookCategoryDB.cpp AddressBookCategoryDB.h AddressBookDB.cpp AddressBookDB.h AddressBookDBDef.h AddressBookDetails.cpp AddressBookDetails.h AddressBookDlg.cpp AddressBookDlg.h AddressBookList.cpp AddressBookList.h CategoryDB.cpp CategoryDB.h CategoryDBDef.h CategoryDeleteDlg.h CategoryEditor.cpp CategoryEditor.h CategoryEditorList.cpp CategoryEditorList.h CustomFieldDB.cpp CustomFieldDB.h CustomFieldDBDef.h CustomFieldEditor.cpp CustomFieldEditor.h DatePicker.cpp DatePicker.h DatePickerDlg.cpp DatePickerDlg.h Dialog.h FLTKUtil.cpp FLTKUtil.h FindDlg.cpp FindDlg.h FindList.cpp FindList.h HelpID.h ImageBox.cpp ImageBox.h Images.cpp Images.h InfoDB.cpp InfoDB.h InfoDBDef.h InfoGroup.cpp InfoGroup.h IniDlg.cpp IniDlg.h InputBox.cpp InputBox.h InputNotify.cpp InputNotify.h LeftGroup.cpp LeftGroup.h ListByDlg.cpp ListByDlg.h Makefile Messages.h Note.cpp Note.h NoteDB.cpp NoteDB.h NoteDBDef.h NoteDetails.c! pp NoteDetails.h NoteEditor.cpp NoteEditor.h NoteEditorDlg.cpp NoteEditorDlg.h NoteList.cpp NoteList.h Notes.cpp Notes.h NotesCategoryDB.cpp NotesCategoryDB.h NxDb0001.txt NxDb0002.txt NxDb0003.txt NxDb0004.txt NxDb0005.txt NxDb0006.txt NxDb0007.txt NxDb0008.txt NxDb0009.txt NxDbAccess.cpp NxDbAccess.h NxDbColumn.cpp NxDbColumn.h NxDbRow.cpp NxDbRow.h Options.cpp Options.h OptionsDlg.cpp OptionsDlg.h PixilDT.cpp PixilDT.dsp PixilDT.dsw PixilDT.h PixilDT.ini PixilDTApp.cpp PixilMainWnd.cpp PixilMainWnd.h Printer.cpp Printer.h ScheduleContainer.cpp ScheduleContainer.h ScheduleDay.cpp ScheduleDay.h ScheduleEvent.cpp ScheduleEvent.h ScheduleHours.cpp ScheduleHours.h Scheduler.cpp Scheduler.h SchedulerCategoryDB.cpp SchedulerCategoryDB.h SchedulerChangeTypeDlg.cpp SchedulerChangeTypeDlg.h SchedulerDB.cpp SchedulerDB.h SchedulerDBDef.h SchedulerDaily.cpp SchedulerDaily.h SchedulerDlg.cpp SchedulerDlg.h SchedulerMonthly.cpp SchedulerMonthly.h SchedulerRepeatData.cpp SchedulerRepea! tData.h SchedulerRepeatDlg.cpp SchedulerRepeatDlg.h SchedulerTimeDlg.c

amadeus dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:26:59 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/pixil/pixilDT/src
In directory antilope:/tmp/cvs-serv11916/pixilDT/src

Added Files:
	AddressBook.cpp AddressBook.h AddressBookCategoryDB.cpp 
	AddressBookCategoryDB.h AddressBookDB.cpp AddressBookDB.h 
	AddressBookDBDef.h AddressBookDetails.cpp AddressBookDetails.h 
	AddressBookDlg.cpp AddressBookDlg.h AddressBookList.cpp 
	AddressBookList.h CategoryDB.cpp CategoryDB.h CategoryDBDef.h 
	CategoryDeleteDlg.h CategoryEditor.cpp CategoryEditor.h 
	CategoryEditorList.cpp CategoryEditorList.h CustomFieldDB.cpp 
	CustomFieldDB.h CustomFieldDBDef.h CustomFieldEditor.cpp 
	CustomFieldEditor.h DatePicker.cpp DatePicker.h 
	DatePickerDlg.cpp DatePickerDlg.h Dialog.h FLTKUtil.cpp 
	FLTKUtil.h FindDlg.cpp FindDlg.h FindList.cpp FindList.h 
	HelpID.h ImageBox.cpp ImageBox.h Images.cpp Images.h 
	InfoDB.cpp InfoDB.h InfoDBDef.h InfoGroup.cpp InfoGroup.h 
	IniDlg.cpp IniDlg.h InputBox.cpp InputBox.h InputNotify.cpp 
	InputNotify.h LeftGroup.cpp LeftGroup.h ListByDlg.cpp 
	ListByDlg.h Makefile Messages.h Note.cpp Note.h NoteDB.cpp 
	NoteDB.h NoteDBDef.h NoteDetails.cpp NoteDetails.h 
	NoteEditor.cpp NoteEditor.h NoteEditorDlg.cpp NoteEditorDlg.h 
	NoteList.cpp NoteList.h Notes.cpp Notes.h NotesCategoryDB.cpp 
	NotesCategoryDB.h NxDb0001.txt NxDb0002.txt NxDb0003.txt 
	NxDb0004.txt NxDb0005.txt NxDb0006.txt NxDb0007.txt 
	NxDb0008.txt NxDb0009.txt NxDbAccess.cpp NxDbAccess.h 
	NxDbColumn.cpp NxDbColumn.h NxDbRow.cpp NxDbRow.h Options.cpp 
	Options.h OptionsDlg.cpp OptionsDlg.h PixilDT.cpp PixilDT.dsp 
	PixilDT.dsw PixilDT.h PixilDT.ini PixilDTApp.cpp 
	PixilMainWnd.cpp PixilMainWnd.h Printer.cpp Printer.h 
	ScheduleContainer.cpp ScheduleContainer.h ScheduleDay.cpp 
	ScheduleDay.h ScheduleEvent.cpp ScheduleEvent.h 
	ScheduleHours.cpp ScheduleHours.h Scheduler.cpp Scheduler.h 
	SchedulerCategoryDB.cpp SchedulerCategoryDB.h 
	SchedulerChangeTypeDlg.cpp SchedulerChangeTypeDlg.h 
	SchedulerDB.cpp SchedulerDB.h SchedulerDBDef.h 
	SchedulerDaily.cpp SchedulerDaily.h SchedulerDlg.cpp 
	SchedulerDlg.h SchedulerMonthly.cpp SchedulerMonthly.h 
	SchedulerRepeatData.cpp SchedulerRepeatData.h 
	SchedulerRepeatDlg.cpp SchedulerRepeatDlg.h 
	SchedulerTimeDlg.cpp SchedulerTimeDlg.h SchedulerWeekly.cpp 
	SchedulerWeekly.h SchedulerYearly.cpp SchedulerYearly.h 
	SpinInput.cpp SpinInput.h SplashDlg.cpp SplashDlg.h Sync.cpp 
	Sync.h TableBase.cpp TableBase.h TimeFunc.cpp TimeFunc.h 
	ToDoList.cpp ToDoList.h ToDoListCategoryDB.cpp 
	ToDoListCategoryDB.h ToDoListDB.cpp ToDoListDB.h 
	ToDoListDBDef.h ToDoListDetails.cpp ToDoListDetails.h 
	ToDoListList.cpp ToDoListList.h ToDoListShowDlg.cpp 
	ToDoListShowDlg.h Toolbar.cpp Toolbar.h ToolbarButton.cpp 
	ToolbarButton.h VCMemoryLeak.h config.h list resource.h 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: Messages.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Messages passed between widgets with do_callback             //
//--------------------------------------------------------------//
#ifndef MESSAGES_H_

#define MESSAGES_H_
enum PixilDTMessage
{ ADDRESS_BOOK_REQUESTED = 1, NOTES_REQUESTED, SCHEDULER_REQUESTED, TODO_LIST_REQUESTED, ADDRESS_BOOK_CHANGED, NOTES_CHANGED, SCHEDULER_CHANGED, TODO_LIST_CHANGED, ADDRESS_BOOK_DELETE, NOTES_DELETE, SCHEDULER_DELETE, TODO_LIST_DELETE, ADDRESS_BOOK_GOTO,	// Requires second parameter - physical record number to go to
    NOTES_GOTO,			// Requires second parameter - physical record number to go to
    SCHEDULER_GOTO,		// Requires second parameter - physical record number to go to
    TODO_LIST_GOTO,		// Requires second parameter - physical record number to go to
    ADDRESS_BOOK_NEW, NOTES_NEW, SCHEDULER_NEW, TODO_LIST_NEW, ADDRESS_BOOK_CATEGORY_DELETED,	// Requires second parameter - category ID of deleted record
    NOTES_CATEGORY_DELETED,	// Requires second parameter - category ID of deleted record
    SCHEDULER_CATEGORY_DELETED,	// Requires second parameter - category ID of deleted record
    TODO_LIST_CATEGORY_DELETED,	// Requires second parameter - category ID of deleted record
    CATEGORY_DELETED,		// Requires second parameter - category ID of deleted record
    ADDRESS_BOOK_CATEGORY_ADDED, NOTES_CATEGORY_ADDED, SCHEDULER_CATEGORY_ADDED, TODO_LIST_CATEGORY_ADDED, CATEGORY_ADDED, ADDRESS_BOOK_CATEGORY_RENAMED, NOTES_CATEGORY_RENAMED, SCHEDULER_CATEGORY_RENAMED, TODO_LIST_CATEGORY_RENAMED, CATEGORY_RENAMED, FIND_ITEM_REQUESTED,	// Requires second parameter - line in the FindDlg results
    ENABLE_TOOLBAR_BUTTON,	// Requires seocnd parameter - the normal image of the toolbar button
    DISABLE_TOOLBAR_BUTTON,	// Requires seocnd parameter - the normal image of the toolbar button
    SHOW_LIST_BY,		// Address Book/List By dialog has been requested
    SHOW_TODO_OPTIONS,		// ToDo List/Show Options dialog has been requested
    SELECTION_CHANGING,		// The selection between the four main parts of the application is changing
    APPLICATION_CLOSING,	// The application is closing, data must be saved
    BEGIN_WEEK_CHANGED,		// The beginning day of week has been changed
    ADDRESS_BOOK_PRINT,		// Print the address book
    NOTES_PRINT,		// Print the notes
    SCHEDULER_PRINT,		// Print the current scheduler page
    TODO_LIST_PRINT,		// Print the to do list
    EDIT_CUT,			// Perform an edit cut operation
    EDIT_COPY,			// Perform an edit copy operation
    EDIT_PASTE,			// Perform an edit paste operation
    EDIT_UNDO,			// Perform an edit undo operation
    EDIT_CUT_AVAILABLE,		// Is an edit/cut operation available, returns 1 or 0
    EDIT_COPY_AVAILABLE,	// Is an edit/copy operation available, returns 1 or 0
    EDIT_PASTE_AVAILABLE,	// Is an edit/paste operation available, returns 1 or 0
    EDIT_UNDO_AVAILABLE,	// Is an edit/undo operation available, returns 1 or 0
    FIX_MENU,			// Fix the main window's menu and toolbar
};

#endif /*  */

--- NEW FILE: Options.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Global application options.                                  //
//                                                              //
// Options maintained here are:                                 //
//                                                              //
// Application:                                                 //
//  ConfirmDelete - Yes or No                                   //
//  MainPage - 0 through 3 for Scheduler, Address Book, To Do   //
//       List or Notes to be displayed first.                   //
//  SchedulerPage - 0 through 3 for daily, weekly, monthly, or  //
//       yearly page to be displayed first.                     //
//                                                              //
// Database:                                                    //
//  Path - path to the database                                 //
//                                                              //
// Scheduler                                                    //
//  DayBegins - 24 hour based hour that the workday begins      //
//  WeekBegins - 0 for Sunday or 1 for Monday                   //
//                                                              //
// Search:                                                      //
//  String - last search string used                            //
//                                                              //
// ToDoList:                                                    //
//  ShowCategory - Yes or No                                    //
//  ShowCompleted - Yes or No                                   //
//  ShowDueDate - Yes or No                                     //
//  ShowOnlyDue - Yes or No                                     //
//  ShowPriority - Yes or No                                    //
//  Sort - 0 through 3 for sort by priority/due date, due       //
//       date/priority, category/priority, or category/due date //
//--------------------------------------------------------------//
#ifndef OPTIONS_H_

#define OPTIONS_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <string>
#include <FL/Fl_Widget.H>
using namespace std;

// Turn Windows Profile API on or off
#ifdef WIN32
#define WIN32_PROFILE_API	// Undefine this to use the Linux version of the code
#else /*  */
#undef WIN32_PROFILE_API
#endif /*  */
class Options
{
  public:Options();		// Constructor
    ~Options();			// Destructor
    static void Destroy();	// Destroy the singleton Options object
    inline static bool GetConfirmDelete()	// Get the ToDo List's Show Categories setting
    {
	return (GetBooleanValue("Application", "ConfirmDelete", true));
    }
    inline static string GetDatabasePath()	// Get the path to the database
    {
	return (GetStringValue("Database", "Path", "."));
    }
    inline static int GetDayBegins()	// Get the beginning hour of the day for scheduler displays
    {
	return (GetIntValue("Scheduler", "DayBegins"));
    }
    inline static string GetHelpPath()	// Get the help file directory
    {
	return (GetStringValue("Help", "Path", "."));
    }
    inline static int GetMainPage()	// Get the main page to be displayed - 0 through 3
    {
	return (GetIntValue("Application", "MainPage"));
    }
    inline static int GetSchedulerPage()	// Get the scheduler page to be displayed - 0 through 3
    {
	return (GetIntValue("Application", "SchedulerPage"));
    }
    inline static string GetSearchString()	// Get the last search string used
    {
	return (GetStringValue("Search", "String", ""));
    }
    static string GetStringValue(const char *pszSection,
				 const char *pszSetting,
				 const char *pszDefault);
    inline static bool GetToDoShowCategory()	// Get the ToDo List's Show Categories setting
    {
	return (GetBooleanValue("ToDoList", "ShowCategory", false));
    }
    inline static bool GetToDoShowCompleted()	// Get the ToDo List's Show Completed items setting
    {
	return (GetBooleanValue("ToDoList", "ShowCompleted", false));
    }
    inline static bool GetToDoShowDueDate()	// Get the ToDo List's Show Due Dates setting
    {
	return (GetBooleanValue("ToDoList", "ShowDueDate", false));
    }
    inline static bool GetToDoShowOnlyDue()	// Get the ToDo List's Show Only Due setting
    {
	return (GetBooleanValue("ToDoList", "ShowOnlyDue", false));
    }
    inline static bool GetToDoShowPriority()	// Get the ToDo List's Show Priority setting
    {
	return (GetBooleanValue("ToDoList", "ShowPriority", false));
    }
    inline static int GetToDoSort()	// Get the ToDo List's Show Priority setting
    {
	return (GetIntValue("ToDoList", "Sort"));
    }
    inline static int GetWeekBegins()	// Get the beginning day of the week for scheduler displays
    {
	return (GetIntValue("Scheduler", "WeekBegins"));
    }
    inline static void SetConfirmDelete(bool bConfirmDelete)	// Set the confirm delete flag
    {
	SetBooleanValue("Application", "ConfirmDelete", bConfirmDelete);
    }
    inline static void SetDatabasePath(const char *pszString)	// Set the database path
    {
	SetStringValue("DataBase", "Path", pszString);
    }
    inline static void SetDayBegins(int nHour)	// Set the main page to be displayed
    {
	SetIntValue("Scheduler", "DayBegins", nHour);
    }
    inline static void SetMainPage(int nPage)	// Set the main page to be displayed
    {
	SetIntValue("Application", "MainPage", nPage);
    }
    inline static void SetSchedulerPage(int nPage)	// Set the scheduler page to be displayed
    {
	SetIntValue("Application", "SchedulerPage", nPage);
    }
    inline static void SetSearchString(const char *pszString)	// Set the last search string used
    {
	SetStringValue("Search", "String", pszString);
    }
    static void SetStringValue(const char *pszSection,	// Set a string value into the INI file
			       const char *pszSetting, const char *pszValue);
    inline static void SetToDoShowCategory(bool bShowCategory)	// Set the ToDo List's Show Categories setting
    {
	SetBooleanValue("ToDoList", "ShowCategory", bShowCategory);
    }
    inline static void SetToDoShowCompleted(bool bShowCompleted)	// Set the ToDo List's Show Completed items setting
    {
	SetBooleanValue("ToDoList", "ShowCompleted", bShowCompleted);
    }
    inline static void SetToDoShowDueDate(bool bShowDueDate)	// Set the ToDo List's Show Due Dates setting
    {
	SetBooleanValue("ToDoList", "ShowDueDate", bShowDueDate);
    }
    inline static void SetToDoShowOnlyDue(bool bShowOnlyDue)	// Set the ToDo List's Show Only Due setting
    {
	SetBooleanValue("ToDoList", "ShowOnlyDue", bShowOnlyDue);
    }
    inline static void SetToDoShowPriority(bool bShowPriority)	// Set the ToDo List's Show Priority setting
    {
	SetBooleanValue("ToDoList", "ShowPriority", bShowPriority);
    }
    inline static void SetToDoSort(int nSort)	// Set the ToDo List's Sort order setting
    {
	SetIntValue("ToDoList", "Sort", nSort);
    }
    inline static void SetWeekBegins(int nHour)	// Set the main page to be displayed
    {
	SetIntValue("Scheduler", "WeekBegins", nHour);
    }
  private:static Options *m_pThis;
    // Singleton pointer
    string m_strIniFile;	// Name of the INI file
    int m_UserIniFile;

#ifndef WIN32_PROFILE_API
    void *m_pINIFileReader;	// Pointer to the INI File Reader object
#endif /*  */
    static bool GetBooleanValue(const char *pszSection,	// Get a boolean value from the INI file
				const char *pszSetting, bool bDefault);
    static int GetIntValue(const char *pszSection,	// Get an integer value from the INI file
			   const char *pszSetting);
    static void SetBooleanValue(const char *pszSection,	// Set a boolean value into the INI file
				const char *pszSetting, bool bValue);
    static void SetIntValue(const char *pszSection,	// Set an integer value into the INI file
			    const char *pszSetting, int nValue);
    static void SetIniFileName();	// Get the INI file name
};


#endif /*  */

--- NEW FILE: IniDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Dialog used when the INI file location cannot be found in    //
// the Windows registry.                                        //
//--------------------------------------------------------------//
#ifndef INIDLG_H_

#define INIDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <FL/Fl_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Window.H>
using namespace std;
class IniDlg:public Fl_Window
{
  public:IniDlg();		// Default constructor
    ~IniDlg();			// Destructor
    int DoModal();		// Run the modal dialog
    string GetDataPath() const	// Get the entered path
    {
	return (m_strPath);
    }
  private:  Fl_Button * m_pBrowseButton;
    // Browse button
    Fl_Button *m_pCancelButton;	// Cancel button
    Fl_Button *m_pHelpButton;	// Help button
    Fl_Button *m_pOKButton;	// OK Button
    Fl_Input *m_pDataDir;	// Data directory
    string m_strPath;		// The final path
    static void OnBrowseButton(Fl_Widget * pWidget,	// Process a click on the browse button
			       void *pUserData);
    static void OnHelpButton(Fl_Widget * pWidget,	// Process a click on the help button
			     void *pUserData);
    static bool Validate(const char *pszString,	// Validate a new data directory
			 Fl_Widget * pThis, void *pData);
    static bool ValidateDirectory(const char *pszDirectory,	// Validate an entered directory in detail
				  string & strPath);
};


#endif /*  */

--- NEW FILE: LeftGroup.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the left portion of the main window for PixilDT.   //
//--------------------------------------------------------------//
#include "config.h"
#include "FLTKUtil.h"
#include "Images.h"
#include "LeftGroup.h"
#include "PixilMainWnd.h"

#include "VCMemoryLeak.h"


#define BUTTON_HEIGHT 52
#define BUTTON_WIDTH  50
#define FIRST_BUTTON  15


//--------------------------------------------------------------//
// Default constructor                                          //
//--------------------------------------------------------------//
LeftGroup::LeftGroup(int nX, int nY, int nWidth, int nHeight)
    :
Fl_Group(nX, nY, nWidth, nHeight, "")
{
    int nLeft = ((nWidth - BUTTON_WIDTH) >> 1);

    // Set the background color
    box(FL_ENGRAVED_BOX);

    // Create each of four boxes, these are added to the current group by default
    new ImageBox(x() + nLeft,
		 y() + FIRST_BUTTON,
		 BUTTON_WIDTH,
		 BUTTON_HEIGHT,
		 Images::GetSchedulerImage(), SCHEDULER_REQUESTED, _("Date"));
    new ImageBox(x() + nLeft,
		 y() + FIRST_BUTTON + 1 * (BUTTON_HEIGHT + 10),
		 BUTTON_WIDTH,
		 BUTTON_HEIGHT,
		 Images::GetAddressBookImage(),
		 ADDRESS_BOOK_REQUESTED, _("Address"));
    new ImageBox(x() + nLeft,
		 y() + FIRST_BUTTON + 2 * (BUTTON_HEIGHT + 10),
		 BUTTON_WIDTH,
		 BUTTON_HEIGHT,
		 Images::GetToDoListImage(), TODO_LIST_REQUESTED, _("To Do"));
    new ImageBox(x() + nLeft,
		 y() + FIRST_BUTTON + 3 * (BUTTON_HEIGHT + 10),
		 BUTTON_WIDTH,
		 BUTTON_HEIGHT,
		 Images::GetNotesImage(), NOTES_REQUESTED, _("Memo"));

    resizable(new
	      Fl_Box(x(), y() + FIRST_BUTTON + 4 * (BUTTON_HEIGHT + 10), w(),
		     h() - FIRST_BUTTON - 4 * (BUTTON_HEIGHT + 10)));

    end();

    // Show this group
    show();
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
LeftGroup::Message(PixilDTMessage nMessage, int nInfo)
{
    ImageBox *pImageBox;
    int i;
    int nReturn = 0;		// Default return value

    // Call each child with this message (any that are down will pop-up like a radio button)
    for (i = 0; i < children(); ++i) {
	pImageBox = dynamic_cast < ImageBox * >(child(i));
	if (pImageBox != NULL) {
	    pImageBox->Message(nMessage, 0);
	}
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Called by one of the child widgets to indicate that a button //
// was pressed.                                                 //
//--------------------------------------------------------------//
void
LeftGroup::Notify(PixilDTMessage nMessage, int nInfo)
{
    // Notify the parent
    dynamic_cast < PixilMainWnd * >(parent())->Notify(nMessage, 0);

//      // Call each child with this message (any that are down will pop-up like a radio button)
//      Message(nMessage,0);
}

--- NEW FILE: PixilDT.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Main window for PixilDT prototype.                           //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include <FL/x.H>
#ifdef WIN32
#include "../getopt/getopt.h"
#endif
#include "HelpID.h"
#include "Images.h"
#include "Options.h"
#include "PixilDT.h"
#include "PixilMainWnd.h"
#ifdef WIN32
#include "resource.h"
#endif

#ifdef WIN32
#include <direct.h>
#endif

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Singleton pointer.                                           //
//--------------------------------------------------------------//
PixilDT *
    PixilDT::m_pThis =
    NULL;


//--------------------------------------------------------------//
// Constructor.                                                 //
//--------------------------------------------------------------//
PixilDT::PixilDT(int argc, char **argv)
{
#ifdef DEBUG
    // Temp workaround, set the LANG environment variable to the language to translate to
    putenv("LANG=it");
#endif

    // Set the singleton pointer
    m_pThis = this;

    // Set up the proper locale and facets
    try {
	setlocale(LC_ALL, getenv("LANG"));
    }
    catch(...) {
	// Leave the locale at its default
    }

    // Determine the date formatting for validating entered dates
    DetermineDateFormat();

    // Translate button titles used in FLTK
    fl_no = _("&No");
    fl_yes = _("&Yes");
    fl_ok = _("&OK");
    fl_cancel = _("Cancel");

    // Set up the background color for FLTK
    Fl::get_system_colors();

    // Create the main window
    m_pMainWindow = new PixilMainWnd(argc, argv);
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
PixilDT::~PixilDT()
{
    delete m_pMainWindow;
}


//--------------------------------------------------------------//
// Determine the current local's date format based on the       //
// output of strftime.                                          //
//--------------------------------------------------------------//
void
PixilDT::DetermineDateFormat()
{
    char *pszSep[2];
    char szData[16];
    char szDate[64];
    int i;
    int nFirst;
    int nLength;
    int nMax;
    int nSecond;
    //int nThird;
    time_t nDate;
    struct tm TM;

    // Get February 1st, 2003 formatted by strftime, to determine the date formatting order
    memset(&TM, 0, sizeof(TM));
    TM.tm_year = 2003 - 1900;
    TM.tm_mon = 1;
    TM.tm_mday = 1;
    TM.tm_hour = 12;
    nDate = mktime(&TM);
    strftime(szDate, sizeof(szDate), "%x", localtime(&nDate));

    // Find separators in the formatted date
    pszSep[0] = NULL;
    pszSep[1] = NULL;
    nMax = strlen(szDate);
    m_cDateSeparator = '/';	// Just in case none found
    for (i = 0; i < nMax; ++i) {
	if (!isdigit(szDate[i])) {
	    if (pszSep[0] == NULL) {
		pszSep[0] = &szDate[i];

		// Save the date separator
		m_cDateSeparator = szDate[i];
	    } else {
		pszSep[1] = &szDate[i];
		break;
	    }
	}
    }

    // Two delimiters found ?
    if (pszSep[1] != NULL) {
	nLength = pszSep[0] - szDate;
	strncpy(szData, szDate, nLength);
	szData[nLength] = '\0';
	nFirst = atoi(szData);
	nLength = pszSep[1] - pszSep[0] - 1;
	strncpy(szData, pszSep[0] + 1, nLength);
	szData[nLength] = '\0';
	nSecond = atoi(szData);
	//nLength=nMax+szDate-pszSep[1]-1;
	//strncpy(szData,pszSep[1]+1,nLength);
	//szData[nLength]='\0';
	//nThird=atoi(szData);
	if (nFirst == 1) {
	    // First is day
	    if (nSecond == 2) {
		m_nDateFormat = DATE_DMY;
	    } else {
		m_nDateFormat = DATE_DYM;
	    }
	} else if (nFirst == 2) {
	    // First is month
	    if (nSecond == 1) {
		m_nDateFormat = DATE_MDY;
	    } else {
		m_nDateFormat = DATE_MYD;
	    }
	} else			//if (nFirst==3||nFirst==2003)
	{
	    // First is year
	    if (nSecond == 1) {
		m_nDateFormat = DATE_YDM;
	    } else {
		m_nDateFormat = DATE_YMD;
	    }
	}
    } else {
	// Two delimiters were not found
	m_nDateFormat = DATE_YMD;
    }

    // Determine the time separator character
    strftime(szDate, sizeof(szDate), "%X", localtime(&nDate));
    nMax = strlen(szDate);
    for (i = 0; i < nMax; ++i) {
	if (!isdigit(szDate[i])) {
	    m_cTimeSeparator = szDate[i];
	    break;
	}
    }

    // Get the strings used for AM/PM
    memset(&TM, 0, sizeof(TM));
    TM.tm_year = 80;
    //TM.tm_mon=0; // January
    TM.tm_mday = 2;
    TM.tm_hour = 6;
    nDate = mktime(&TM);
    strftime(szData, sizeof(szData), "%p", localtime(&nDate));
    m_strAM = szData;
    nDate += 12 * 60 * 60;
    strftime(szData, sizeof(szData), "%p", localtime(&nDate));
    m_strPM = szData;
}


//--------------------------------------------------------------//
// Set the Pixil Icon for a window.  This has to be done for    //
// the first window to be displayed since that window will      //
// register the FLTK window class for the WIN32 version of the  //
// code.                                                        //
//--------------------------------------------------------------//
void
PixilDT::SetPixilIcon(Fl_Window * pWindow)
{

#ifndef WIN32

    // Set the icon for X Windows
    pWindow->icon((char *) Images::GetPixmap(Images::PIXIL_ICON));

#else

    // Load the window icon from the resource file
    pWindow->
	icon((char *) LoadIcon(fl_display, MAKEINTRESOURCE(IDI_PIXIL_ICON)));

#endif

}


//--------------------------------------------------------------//
// Show help for a given help ID.                               //
//--------------------------------------------------------------//
void
PixilDT::ShowHelp(int nHelpID)
{
    static const char *pszHelpInfo[] = {
	"AddressBookCategory.html",
	"AddressBookDlg.html",
	"CategoryEditor.html",
	"CustomFieldEditor.html",
	"FindDlg.html",
	"ListByDlg.html",
	"NewUser.html",
	"NotesCategory.html",
	"NoteEditorDlg.html",
	"OptionsDlg.html",
	"SchedulerCategory.html",
	"SchedulerDlg.html",
	"SchedulerRepeatDlg.html",
	"SchedulerTimeDlg.html",
	"ToDoListCategory.html",
	"ToDoShowDlg.html",
    };
    static const HelpID nHelpIDList[] = {
	HELP_ADDRESS_BOOK_CATEGORY,	// Help on address book categories
	HELP_ADDRESS_BOOK_DLG,	// Help on the Address Book update dialog
	HELP_CATEGORY_EDITOR,	// Help on the Category Editor
	HELP_CUSTOM_FIELD_EDITOR,	// Help on the Custom Field Editor
	HELP_FIND_DLG,		// Help on the Find dialog
	HELP_LISTBY_DLG,	// Help on the Address Book/List By dialog
	HELP_NEW_USER,		// Help for the new user dialog
	HELP_NOTES_CATEGORY,	// Help on notes categories
	HELP_NOTE_EDITOR_DLG,	// Help on the Note Editor dialog
	HELP_OPTIONS_DLG,	// Help on the Options dialog
	HELP_SCHEDULER_CATEGORY,	// Help on scheduler categories
	HELP_SCHEDULER_DLG,	// Help on the Scheduler update dialog
	HELP_SCHEDULER_REPEAT_DLG,	// Help on the Scheduler Repeat entry dialog
	HELP_SCHEDULER_TIME_DLG,	// Help on the Scheduler time entry dialog
	HELP_TODO_LIST_CATEGORY,	// Help on ToDO list categories
	HELP_TODO_SHOW_DLG,	// Help on the ToDo List Show dialog
    };
    string strCmd;
    string strPath;
    unsigned int nIndex;

    // Find this help ID in the list
    for (nIndex = 0; nIndex < sizeof(nHelpIDList); ++nIndex) {
	if (nHelpIDList[nIndex] == nHelpID) {
	    break;
	}
    }

    if (nIndex >= sizeof(nHelpIDList)) {
	// Help not available
	fl_alert(_("Help is not yet available for this topic"));
	return;			// early exit
    }
#ifndef WIN32

    // Unix/Linux - no help yet
    fl_alert(_("Help is not yet implemented"));

#else

    bool bHaveBrowser = false;
    char szBrowser[256];
    char szData[256];
    char szKey[2];
    unsigned long nSize;
    unsigned long nType;
    HKEY hKey;

    // MS/Windows - find the browser from the registry and launch it
    if (::RegOpenKeyEx(HKEY_CURRENT_USER,
		       "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.htm\\OpenWithList",
		       0, KEY_READ, &hKey) == ERROR_SUCCESS) {
	// Get the Most recently used list for this file extension
	nSize = sizeof(szData);
	if (::
	    RegQueryValueEx(hKey, "MRUList", 0, &nType,
			    (unsigned char *) szData,
			    &nSize) == ERROR_SUCCESS) {
	    // Get the name of the executable
	    szKey[0] = szData[0];
	    szKey[1] = '\0';
	    nSize = sizeof(szData);
	    if (::
		RegQueryValueEx(hKey, szKey, 0, &nType,
				(unsigned char *) szBrowser,
				&nSize) == ERROR_SUCCESS) {
		bHaveBrowser = true;
	    }
	}
	// Close the registry key
	::RegCloseKey(hKey);
    }
    // Get the path to the browser
    if (bHaveBrowser == true) {
	bHaveBrowser = false;
	strCmd = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";
	strCmd += szBrowser;
	if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
			   strCmd.c_str(),
			   0, KEY_READ, &hKey) == ERROR_SUCCESS) {
	    // Get the Most recently used list for this file extension
	    nSize = sizeof(szData);
	    if (::
		RegQueryValueEx(hKey, NULL, 0, &nType,
				(unsigned char *) szData,
				&nSize) == ERROR_SUCCESS) {
		::GetShortPathName(szData, szBrowser, sizeof(szBrowser));
		bHaveBrowser = true;
	    }
	    // Close the registry key
	    ::RegCloseKey(hKey);
	}
    }
    // Now launch the browser if one is there
    if (bHaveBrowser == true) {
	strCmd = szBrowser;
	strCmd += " file://";

	strPath = Options::GetHelpPath();
	if (strPath == ".") {
	    char szPath[_MAX_PATH];

	    getcwd(szPath, sizeof(szPath));
	    strPath = szPath;
	}
	strCmd += strPath;
	strCmd += "/";
	strCmd += pszHelpInfo[nIndex];
	system(strCmd.c_str());
    }
#endif

}

--- NEW FILE: PixilDT.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Main application for PixilDT prototype.                      //
//--------------------------------------------------------------//
#ifndef PIXILDT_H_

#define PIXILDT_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <FL/Fl_Window.H>
#include "PixilMainWnd.h"
class PixilDT
{
  public:enum DateFormat	// Date formating types
    { DATE_DMY = 0, DATE_DYM, DATE_MDY, DATE_MYD, DATE_YDM, DATE_YMD,
    };
      PixilDT(int argc, char **argv);	// Constructor
     ~PixilDT();		// Destructor
    inline static void GetAMPM(string & strAM,	// Get the strings used for AM and PM
			       string & strPM)
    {
	strAM = m_pThis->m_strAM;
	strPM = m_pThis->m_strPM;
    }
    inline static PixilDT *GetApp()	// Get a pointer to the one and only app class
    {
	return (m_pThis);
    }
    inline PixilMainWnd *GetMainWindow() const	// Get the main application window
    {
	return (m_pMainWindow);
    }
    inline static DateFormat GetDateFormat()	// Get the locale's date formatting
    {
	return (m_pThis->m_nDateFormat);
    }
    inline static char GetDateSeparator()	// Get the date separator character
    {
	return (m_pThis->m_cDateSeparator);
    }
    inline static char GetTimeSeparator()	// Get the time separator character
    {
	return (m_pThis->m_cTimeSeparator);
    }
    static void SetPixilIcon(Fl_Window * pWindow);	// Set the Pixil Icon for a window
    void ShowHelp(int nHelpID);	// Show help for a given help ID
  private:char m_cDateSeparator;
    // The date separator character
    char m_cTimeSeparator;	// The time separator character
    DateFormat m_nDateFormat;	// The current locale's date formatting
    PixilMainWnd *m_pMainWindow;	// Container window
    static PixilDT *m_pThis;	// Singleton pointer
    string m_strAM;		// Code for AM times
    string m_strPM;		// Code for PM times
    void DetermineDateFormat();	// Determine which date format is in use for the locale
};


#endif /*  */

--- NEW FILE: SchedulerChangeTypeDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Address Book Dialog.                                         //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include <FL/Fl_Box.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "SchedulerChangeTypeDlg.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT       (5*DLG_BUTTON_HEIGHT)
#define DLG_WIDTH        (5*DLG_BORDER+4*DLG_BUTTON_WIDTH)


//--------------------------------------------------------------//
// Constructor, nRow is the row number in the address book      //
// database as currently sorted or a -1 if this is to be a new  //
// row.                                                         //
//--------------------------------------------------------------//
SchedulerChangeTypeDlg::SchedulerChangeTypeDlg(Fl_Widget * pParent,
					       bool bDelete)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Repeating Event"))
{
    const char *pszMessage;
    Fl_Box *pBox;

    // Create the box for the message
    if (bDelete == false) {
	pszMessage =
	    _
	    ("Should these changes be made to the current instance of this event, "
	     "to the current and future instances of this event, "
	     "or to all instances of this event ?");
    } else {
	pszMessage =
	    _("Should the current instance of this event be deleted, "
	      " the current instance and all future events be deleted, "
	      " or all instances of this event be deleted ?");
    }
    pBox = new Fl_Box(DLG_BORDER,
		      DLG_BORDER,
		      w() - 2 * DLG_BORDER,
		      h() - DLG_BUTTON_HEIGHT - 2 * DLG_BORDER, pszMessage);
    pBox->
	align(FL_ALIGN_LEFT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);

    // Create the buttons
    m_pCurrentButton = new Fl_Button(DLG_BORDER,
				     h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
				     DLG_BUTTON_WIDTH,
				     DLG_BUTTON_HEIGHT, _("&Current"));
    m_pCurrentButton->callback(OnCurrentButton);
    m_pFutureButton = new Fl_Button(2 * DLG_BORDER + DLG_BUTTON_WIDTH,
				    h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
				    DLG_BUTTON_WIDTH,
				    DLG_BUTTON_HEIGHT, _("+ &Future"));
    m_pFutureButton->callback(OnFutureButton);
    m_pAllButton = new Fl_Button(3 * DLG_BORDER + 2 * DLG_BUTTON_WIDTH,
				 h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
				 DLG_BUTTON_WIDTH,
				 DLG_BUTTON_HEIGHT, _("All"));
    m_pAllButton->callback(OnAllButton);
    m_pCancelButton = new Fl_Button(4 * DLG_BORDER + 3 * DLG_BUTTON_WIDTH,
				    h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
				    DLG_BUTTON_WIDTH,
				    DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");

    end();

    // The DoModal method will call show on this window
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
SchedulerChangeTypeDlg::~SchedulerChangeTypeDlg()
{
}


//--------------------------------------------------------------//
// Run the dialog.                                              //
//--------------------------------------------------------------//
int
SchedulerChangeTypeDlg::DoModal()
{
    // Preset to the window being closed early
    m_nChangeType = SCHEDULER_CHANGE_TYPE_NONE;

    // Run the dialog
    ::DoModal(this, NULL, m_pCancelButton);

    // Indicate that the (non-existant) OK button was pressed
    return (1);
}


//--------------------------------------------------------------//
// All button was clicked (static callback).                    //
//--------------------------------------------------------------//
void
SchedulerChangeTypeDlg::OnAllButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerChangeTypeDlg *pThis =
	(SchedulerChangeTypeDlg *) (pWidget->parent());

    pThis->m_nChangeType = SCHEDULER_CHANGE_TYPE_ALL;
    pThis->do_callback();
}


//--------------------------------------------------------------//
// Current button was clicked (static callback).                //
//--------------------------------------------------------------//
void
SchedulerChangeTypeDlg::OnCurrentButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerChangeTypeDlg *pThis =
	(SchedulerChangeTypeDlg *) (pWidget->parent());

    pThis->m_nChangeType = SCHEDULER_CHANGE_TYPE_CURRENT_ONLY;
    pThis->do_callback();
}


//--------------------------------------------------------------//
// Future button was clicked (static callback).                 //
//--------------------------------------------------------------//
void
SchedulerChangeTypeDlg::OnFutureButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerChangeTypeDlg *pThis =
	(SchedulerChangeTypeDlg *) (pWidget->parent());

    pThis->m_nChangeType = SCHEDULER_CHANGE_TYPE_CURRENT_FUTURE;
    pThis->do_callback();
}

--- NEW FILE: AddressBookCategoryDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Address Book Category database class.                        //
//--------------------------------------------------------------//
#ifndef ADDRESSBOOKCATEGORYDB_H_

#define ADDRESSBOOKCATEGORYDB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "CategoryDB.h"
class AddressBookCategoryDB:public CategoryDB
{
  public:AddressBookCategoryDB();
    // Constructor
    ~AddressBookCategoryDB();	// Destructor
    static AddressBookCategoryDB *GetAddressBookCategoryDB();	// Retrieve the static pointer
  private:static AddressBookCategoryDB *m_pThis;
    // One and only address book category object
};


#endif /*  */

--- NEW FILE: FindDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Find Dialog.                                                 //
//--------------------------------------------------------------//
#ifndef FINDDLG_H_

#define FINDDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <vector>
#include <FL/Fl_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Window.H>
#include "FindList.h"
#include "Messages.h"
#include "NxDbAccess.h"
using namespace std;

//--------------------------------------------------------------//
// Information about rows found so far                          //
//--------------------------------------------------------------//
class FindRow
{
  public:inline FindRow()	// Default constructor
    {
    }
    inline FindRow(const FindRow & Other)	// Copy constructor
    {
	*this = Other;
    }
    inline ~ FindRow()		// Destructor
    {
    }
    inline FindRow & operator=(const FindRow & Other)	// Assignment operator
    {
	m_nPhysicalRow = Other.m_nPhysicalRow;
	m_nType = Other.m_nType;
	m_strKeyValue = Other.m_strKeyValue;
	return (*this);
    }

    // All data is public just like when this used to be a structure
    int m_nPhysicalRow;		// Physical row of of the found item
    PixilDTMessage m_nType;	// Type of row found
    string m_strKeyValue;	// Key value of the record - name, description, etc...
};


//--------------------------------------------------------------//
// The Find dialog class.                                       //
//--------------------------------------------------------------//
class FindDlg:public Fl_Window
{
  public:enum FindAction
    { ActionCancel = 0, ActionGoTo,
    };
      FindDlg(Fl_Widget * pParent);	// Constructor
     ~FindDlg();		// Destructor
    int DoModal();		// Run the modal dialog
    inline int GetAction() const	// Get the action selected by the dialog
    {
	return (m_nAction);
    }
    inline const string & GetFindKey(int nRow)	// Get the string key of a found item
    {

#ifdef DEBUG
	assert(nRow >= 0 && nRow < (int) m_vFindRow.size());

#endif				/*  */
	return (m_vFindRow[nRow].m_strKeyValue);
    }
    inline int GetFindRows()	// Get the number of rows found
    {
	return (m_vFindRow.size());
    }
    inline int GetFindType(int nRow)	// Get the type of a found item
    {

#ifdef DEBUG
	assert(nRow >= 0 && nRow < (int) m_vFindRow.size());

#endif /*  */
	return (m_vFindRow[nRow].m_nType);
    }
    inline int GetRecno() const	// Get the physical record number of the record selected for GoTo
    {
	return (m_nRecno);
    }
    inline PixilDTMessage GetType() const	// Get the type of information being selected
    {
	return (m_nType);
    }
    void Notify(PixilDTMessage nMessage,	// Notification from a child widget
		int nInfo);
  private:FindList * m_pResults;
    // Where the search results are stored
    Fl_Button *m_pCancelButton;	// Cancel button
    Fl_Button *m_pGoToButton;	// GoTo button
    Fl_Button *m_pHelpButton;	// Help button
    Fl_Button *m_pRadioButton[2];	// The radio buttons
    Fl_Button *m_pSearchButton;	// Search button
    Fl_Input *m_pInput;		// The search string
    int m_nAction;		// The final dialog action, Cancel or GoTo
    int m_nRecno;		// Physical record number selected for GoTo
    PixilDTMessage m_nType;	// The message for the type of information selected
    vector < FindRow > m_vFindRow;	// Rows found so far
    static string GetAddressKey(NxDbAccess * pDB,	// Get address book key
				int nRow);
    static string GetNoteKey(NxDbAccess * pDB,	// Get notes key
			     int nRow);
    static string GetSchedulerKey(NxDbAccess * pDB,	// Get Scheduler key
				  int nRow);
    static string GetToDoKey(NxDbAccess * pDB,	// Get ToDo List key
			     int nRow);
    static void OnHelpButton(Fl_Widget * pWidget,	// Process click on the Help button
			     void *pUserData);
    static void OnSearchButton(Fl_Widget * pWidget,	// Process click on the search button
			       void *pUserData);
    void Search(NxDbAccess * pDB,	// Search a data base
		PixilDTMessage nType,
		string(*pfnGetKeyValue) (NxDbAccess *, int));
};


#endif /*  */

--- NEW FILE: CustomFieldDBDef.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// "Info" database definition fields.                           //
//--------------------------------------------------------------//
#ifndef CUSTOMFIELDDBDEF_H_

#define CUSTOMFIELDDBDEF_H_

#define INFO_TYPE 10

// Info
field custFields[] = {
    {
     'i', 1, 0}
    ,				// Field 0:infoid
    {
     'c', INFO_TYPE, 0}
    ,				//       1:info_type
    {
     0}
};


// Database
fildes custFile = {
    0, 0, 0, "dbf", 2, &custFields[0]
};


#endif /*  */

--- NEW FILE: list ---
AddressBookDB.cpp: : NxDbAccess("add",&cFile,cFields)
AddressBookDB.cpp:	NxDbAccess::Delete(nRow);
AddressBookDB.cpp:	NxDbAccess::Export(nRow,vExportString);
AddressBookDB.cpp:	nRow=NxDbAccess::Import(vExportString2);
AddressBookDB.cpp:	int nRow = NxDbAccess::Insert();
AddressBookDB.h:#include "NxDbAccess.h"
AddressBookDB.h:class AddressBookDB:public NxDbAccess
AddressBookList.cpp:bool AddressBookList::SortCategory1(NxDbRow* pRow1,
AddressBookList.cpp:								    NxDbRow* pRow2)
AddressBookList.cpp:bool AddressBookList::SortCategory2(NxDbRow* pRow1,
AddressBookList.cpp:								    NxDbRow* pRow2)
AddressBookList.cpp:bool AddressBookList::SortCompare1(NxDbRow* pRow1,
AddressBookList.cpp:								   NxDbRow* pRow2)
AddressBookList.cpp:bool AddressBookList::SortCompare2(NxDbRow* pRow1,
AddressBookList.cpp:								   NxDbRow* pRow2)
AddressBookList.h:    static bool SortCategory1(NxDbRow * pRow1,	// Sort by last name, first name and filter by category
AddressBookList.h:			      NxDbRow * pRow2);
AddressBookList.h:    static bool SortCategory2(NxDbRow * pRow1,	// Sort by company, last name and filter by category
AddressBookList.h:			      NxDbRow * pRow2);
AddressBookList.h:    static bool SortCompare1(NxDbRow * pRow1,	// Sort by last name, first name
AddressBookList.h:			     NxDbRow * pRow2);
AddressBookList.h:    static bool SortCompare2(NxDbRow * pRow1,	// Sort by company, last name
AddressBookList.h:			     NxDbRow * pRow2);
CategoryDB.cpp: : NxDbAccess(pszFileName,m_pStaticFildes[m_nLastIndexUsed],CreateFields(nCategoryLength))
CategoryDB.cpp:	int nRow = NxDbAccess::Insert();
CategoryDB.cpp:	bReturn=NxDbAccess::TestDuplicate(pszString,
CategoryDB.h:#include "NxDbAccess.h"
CategoryDB.h:class CategoryDB:public NxDbAccess
CustomFieldDB.cpp: : NxDbAccess("add_custfields",&custFile,custFields)
CustomFieldDB.cpp:	int nRow = NxDbAccess::Insert();
CustomFieldDB.h:#include "NxDbAccess.h"
CustomFieldDB.h:class CustomFieldDB:public NxDbAccess
FindDlg.cpp:string FindDlg::GetAddressKey(NxDbAccess* pDB,
FindDlg.cpp:string FindDlg::GetNoteKey(NxDbAccess* pDB,
FindDlg.cpp:string FindDlg::GetSchedulerKey(NxDbAccess* pDB,
FindDlg.cpp:string FindDlg::GetToDoKey(NxDbAccess* pDB,
FindDlg.cpp:void FindDlg::Search(NxDbAccess* pDB,
FindDlg.cpp:					 string (*pfnGetKeyValue)(NxDbAccess*,int))
FindDlg.h:#include "NxDbAccess.h"
FindDlg.h:    static string GetAddressKey(NxDbAccess * pDB,	// Get address book key
FindDlg.h:    static string GetNoteKey(NxDbAccess * pDB,	// Get notes key
FindDlg.h:    static string GetSchedulerKey(NxDbAccess * pDB,	// Get Scheduler key
FindDlg.h:    static string GetToDoKey(NxDbAccess * pDB,	// Get ToDo List key
FindDlg.h:    void Search(NxDbAccess * pDB,	// Search a data base
FindDlg.h:		string(*pfnGetKeyValue) (NxDbAccess *, int));
InfoDB.cpp: : NxDbAccess("add_info",&iFile,iFields)
InfoDB.cpp:	int nRow = NxDbAccess::Insert();
InfoDB.h:#include "NxDbAccess.h"
InfoDB.h:class InfoDB:public NxDbAccess
InfoGroup.cpp:  NxDbAccess::RefreshAll();
Makefile:LIBS=-lflek-native -lfltk-native ../NxDb/libNxDb.a ../sync/libpixil-sync-native.a -lX11
Makefile.old:LDLIBS = -L/usr/local/lib -L$(FLTKDIR)/lib/ -L$(FLEKDIR)/lib/ ../NxDb/libNxDb.a  -lflek_ui -lflek_core -lfltk -L/usr/X11R6/lib -lX11
Makefile.old:$(TARGET): ../NxDb/libNxDb.a $(OBJS) 
NoteDB.cpp: : NxDbAccess("not",&noteFile,noteFields)
NoteDB.cpp:	NxDbAccess::Delete(nRow);
NoteDB.cpp:	NxDbAccess::Export(nRow,vExportString);
NoteDB.cpp:	nRow=NxDbAccess::Import(vExportString2);
NoteDB.cpp:	int nRow = NxDbAccess::Insert();
NoteDB.h:#include "NxDbAccess.h"
NoteDB.h:class NoteDB:public NxDbAccess
NoteList.cpp:bool NoteList::SortCategory(NxDbRow* pRow1,
NoteList.cpp:							NxDbRow* pRow2)
NoteList.cpp:bool NoteList::SortCompare(NxDbRow* pRow1,
NoteList.cpp:						   NxDbRow* pRow2)
NoteList.h:    static bool SortCategory(NxDbRow * pRow1,	// Sort by note title and filter by category
NoteList.h:			     NxDbRow * pRow2);
NoteList.h:    static bool SortCompare(NxDbRow * pRow1,	// Sort by note title
NoteList.h:			    NxDbRow * pRow2);
NxDbAccess.cpp:// Class to access an NxDb database for desktop applications.   //
NxDbAccess.cpp:#include "NxDbAccess.h"
NxDbAccess.cpp:// Pointer to the one and only NxDb object.                     //
NxDbAccess.cpp:NxDb* NxDbAccess::m_pNxDb = NULL;
NxDbAccess.cpp:int NxDbAccess::m_nArgc = 0;
NxDbAccess.cpp:char** NxDbAccess::m_ppszArgv = NULL;
NxDbAccess.cpp:set<NxDbAccess*> NxDbAccess::m_setOpenDB;
NxDbAccess.cpp:int NxDbAccess::m_nSortColumn = -1;
NxDbAccess.cpp:bool (*NxDbAccess::m_pfnCompareRoutine)(NxDbRow*,NxDbRow*);
NxDbAccess.cpp:NxDbAccess::NxDbAccess(const char* pszFileName,
NxDbAccess.cpp:  m_pNxDb = NULL;
NxDbAccess.cpp:void NxDbAccess::Open()
NxDbAccess.cpp:  if (m_pNxDb==NULL)
NxDbAccess.cpp:      m_pNxDb = new NxDb(m_nArgc,m_ppszArgv);
NxDbAccess.cpp:      m_pNxDb->SetPath(Options::GetDatabasePath().c_str());
NxDbAccess.cpp:  if (!m_pNxDb->Open(m_pszFileName,m_pDescription,m_pField,0))
NxDbAccess.cpp:      if (m_pNxDb->Create(m_pszFileName,m_pDescription,m_pField,0))
NxDbAccess.cpp:	  if (m_pNxDb->Open(m_pszFileName,m_pDescription,m_pField,0))
NxDbAccess.cpp:NxDbAccess::~NxDbAccess()
NxDbAccess.cpp:	// Destroy the NxDb object if this is the last NxDbAccess object
NxDbAccess.cpp:		delete m_pNxDb;
NxDbAccess.cpp:		m_pNxDb=NULL;
NxDbAccess.cpp:void NxDbAccess::Close()
NxDbAccess.cpp:      set<NxDbAccess*>::iterator iter;
NxDbAccess.cpp:	  m_pNxDb->Close(m_strDbName.c_str());
NxDbAccess.cpp:void NxDbAccess::RefreshAll()
NxDbAccess.cpp:  // The destructor for NxDbAccess removes entries from the set m_setOpenDB
NxDbAccess.cpp:  set<NxDbAccess*>::iterator iter;
NxDbAccess.cpp:  set<NxDbAccess*> tmp;
NxDbAccess.cpp:void NxDbAccess::CloseAll()
NxDbAccess.cpp:  NxDbAccess* pNxDbAccess;
NxDbAccess.cpp:  // The destructor for NxDbAccess removes entries from the set m_setOpenDB
NxDbAccess.cpp:      pNxDbAccess=*(m_setOpenDB.begin());
NxDbAccess.cpp:      delete pNxDbAccess;
NxDbAccess.cpp:bool NxDbAccess::CompareCustom(NxDbRow* pRow1,
NxDbAccess.cpp:							   NxDbRow* pRow2)
NxDbAccess.cpp:int NxDbAccess::CompareDeleted(NxDbRow* pRow1,
NxDbAccess.cpp:							   NxDbRow* pRow2)
NxDbAccess.cpp:bool NxDbAccess::CompareInteger(NxDbRow* pRow1,
NxDbAccess.cpp:								NxDbRow* pRow2)
NxDbAccess.cpp:bool NxDbAccess::ComparePhysicalRecord(NxDbRow* pRow1,
NxDbAccess.cpp:									   NxDbRow* pRow2)
NxDbAccess.cpp:bool NxDbAccess::CompareString(NxDbRow* pRow1,
NxDbAccess.cpp:							   NxDbRow* pRow2)
NxDbAccess.cpp:void NxDbAccess::Delete(int nRow)
NxDbAccess.cpp:void NxDbAccess::DoSort(FNCUSTOMCOMPARE pfnCompareRoutine,
NxDbAccess.cpp:int NxDbAccess::FindRealRow(int nRow,
NxDbAccess.cpp:int NxDbAccess::FindRow(int nCol,
NxDbAccess.cpp:void NxDbAccess::Dump(const char* pszFileName)
NxDbAccess.cpp:	field* pField = m_pNxDb->GetField(m_strDbName);
NxDbAccess.cpp:	fildes* pDesc = m_pNxDb->GetFilDes(m_strDbName);
NxDbAccess.cpp:void NxDbAccess::DumpAll()
NxDbAccess.cpp:	set<NxDbAccess*>::iterator iter;
NxDbAccess.cpp:		sprintf(szFileName,"NxDb%04d.txt",++i);
NxDbAccess.cpp:int NxDbAccess::FindFirst(int nCol,
NxDbAccess.cpp:int NxDbAccess::FindRow(int nCol,
NxDbAccess.cpp:int NxDbAccess::FindPhysicalRecord(int nRecordNumber,
NxDbAccess.cpp:// character string columns as NxDb must have room for a null   //
NxDbAccess.cpp:int NxDbAccess::GetColumnSize(int nCol)
NxDbAccess.cpp:	field* pField = m_pNxDb->GetField(m_strDbName);
NxDbAccess.cpp:	fildes* pFileDesc = m_pNxDb->GetFilDes(m_strDbName);
NxDbAccess.cpp:int NxDbAccess::Insert()
NxDbAccess.cpp:	NxDbRow* pRow;
NxDbAccess.cpp:		pRow=new NxDbRow(m_pNxDb->GetField(m_strDbName));
NxDbAccess.cpp:int NxDbAccess::NumRecsByKey(int nCol,
NxDbAccess.cpp:int NxDbAccess::GetLocalRow(int nRow,
NxDbAccess.cpp:ROW_VECTOR NxDbAccess::GetRows()
NxDbAccess.cpp:int NxDbAccess::Import(const vector<string>& vExportString)
NxDbAccess.cpp:int NxDbAccess::NumRecsByKey(int nCol,
NxDbAccess.cpp:int NxDbAccess::NumUndeletedRecs()
NxDbAccess.cpp:void NxDbAccess::ReadAll()
NxDbAccess.cpp:	int nMax = m_pNxDb->NumRecs(m_strDbName);
NxDbAccess.cpp:	NxDbRow* pRow;
NxDbAccess.cpp:		pRow=new NxDbRow(m_strDbName,i+1,m_pNxDb);
NxDbAccess.cpp:bool NxDbAccess::Save()
NxDbAccess.cpp:		bReturn&=(m_vpRow[i]->Save(m_strDbName,m_pNxDb));
NxDbAccess.cpp:// opening NxDb objects                                         //
NxDbAccess.cpp:void NxDbAccess::SaveCmdLine(int argc,
NxDbAccess.cpp:bool NxDbAccess::Search(int nRow,
NxDbAccess.cpp:		field* pField = m_pNxDb->GetField(m_strDbName);
NxDbAccess.cpp:		fildes* pFileDesc = m_pNxDb->GetFilDes(m_strDbName);
NxDbAccess.cpp:bool NxDbAccess::SearchString(const char* pszHaystack,
NxDbAccess.cpp:void NxDbAccess::SetHighKey(int nRow,
NxDbAccess.cpp:void NxDbAccess::SetHighStringKey(int nRow,
NxDbAccess.cpp:void NxDbAccess::Sort(FNCUSTOMCOMPARE pfnCompareRoutine)
NxDbAccess.cpp:void NxDbAccess::Sort(FNCUSTOMCOMPARE pfnCompareRoutine,
NxDbAccess.cpp:void NxDbAccess::Sort(int nCol)
NxDbAccess.cpp:	bool (*pfnPr)(NxDbRow*,NxDbRow*);
NxDbAccess.cpp:		const field* pField = m_pNxDb->GetField(m_strDbName);
NxDbAccess.cpp:		const fildes* pFileDescription = m_pNxDb->GetFilDes(m_strDbName);
NxDbAccess.cpp:bool NxDbAccess::TestDuplicate(const char* pszString,
NxDbAccess.h:// Class to access an NxDb database for desktop applications.   //
NxDbAccess.h:#include "NxDbRow.h"
NxDbAccess.h:typedef bool(*FNCUSTOMCOMPARE) (NxDbRow * pRow1,	// Custom comparison routine for sorting
NxDbAccess.h:				NxDbRow * pRow2);
NxDbAccess.h:class NxDbAccess
NxDbAccess.h:  public:NxDbAccess(const char *pszFileName,
NxDbAccess.h:      virtual ~ NxDbAccess();	// Destructor, closes the database
NxDbAccess.h:	return (m_pNxDb->NumRecs(m_strDbName));
NxDbAccess.h:    static set < NxDbAccess * >m_setOpenDB;	// List of pointers to currently open data bases
NxDbAccess.h:    static NxDb *m_pNxDb;	// The database object, kept open to prevent file sharing
NxDbAccess.h:    string m_strDbName;		// Name of the data base for NxDb
NxDbAccess.h:    static bool(*m_pfnCompareRoutine) (NxDbRow *, NxDbRow *);	// Kludge - Custom comparison routine currently in use
NxDbAccess.h:    static bool CompareCustom(NxDbRow * pRow1,	// Compare rows using a custom comparison routine
NxDbAccess.h:			      NxDbRow * pRow2);
NxDbAccess.h:    static int CompareDeleted(NxDbRow * pRow1,	// Compare the deleted status of two rows
NxDbAccess.h:			      NxDbRow * pRow2);
NxDbAccess.h:    static bool CompareInteger(NxDbRow * pRow1,	// Compare rows by contents of an integer column
NxDbAccess.h:			       NxDbRow * pRow2);
NxDbAccess.h:    static bool ComparePhysicalRecord(NxDbRow * pRow1,	// Compare rows by physical record number
NxDbAccess.h:				      NxDbRow * pRow2);
NxDbAccess.h:    static bool CompareString(NxDbRow * pRow1,	// Compare rows by contents of a string column
NxDbAccess.h:			      NxDbRow * pRow2);
NxDbColumn.cpp:// Class Used to represent a column in an NxDb database.        //
NxDbColumn.cpp:#include "NxDbColumn.h"
NxDbColumn.cpp:NxDbColumn::NxDbColumn(int nType,
NxDbColumn.cpp:NxDbColumn::~NxDbColumn()
NxDbColumn.cpp:NxDbColumn& NxDbColumn::operator=(const NxDbColumn& Other)
NxDbColumn.cpp:void NxDbColumn::Clear()
NxDbColumn.cpp:string NxDbColumn::Export()
NxDbColumn.cpp:int NxDbColumn::GetIntValue() const
NxDbColumn.cpp:string NxDbColumn::GetStringValue() const
NxDbColumn.cpp:void NxDbColumn::Import(const string& strData)
NxDbColumn.cpp:void NxDbColumn::Output(unsigned char* ucPtr)
NxDbColumn.cpp:void NxDbColumn::SetStringValue(const char* pszValue)
NxDbColumn.cpp:void NxDbColumn::SetType(int nType,
NxDbColumn.cpp:bool NxDbColumn::SetValue(const char* pszValue)
NxDbColumn.cpp:bool NxDbColumn::SetValue(int nValue)
NxDbColumn.cpp:bool NxDbColumn::SetValue(const string& strValue)
NxDbColumn.h:// Class Used to represent a column in an NxDb database.        //
NxDbColumn.h:class NxDbColumn
NxDbColumn.h:      NxDbColumn(int nType,	// Constructor
NxDbColumn.h:    inline NxDbColumn(const NxDbColumn & Other)	// Copy constructor
NxDbColumn.h:     ~NxDbColumn();		// Destructor
NxDbColumn.h:    NxDbColumn & operator=(const NxDbColumn & Other);	// Assignment operator
NxDbRow.cpp:#include "NxDbRow.h"
NxDbRow.cpp:NxDbRow::NxDbRow()
NxDbRow.cpp:NxDbRow::NxDbRow(field* pField)
NxDbRow.cpp:NxDbRow::NxDbRow(const string& strDbName, // Construct from data base info
NxDbRow.cpp:				 NxDb* pNxDb)
NxDbRow.cpp:	pField=pNxDb->GetField(strCopy);
NxDbRow.cpp:		if (pNxDb->Extract(strCopy,nRow,i,szBuffer)==0)
NxDbRow.cpp:			szBuffer[pField[i].size]='\0'; // Workaround to error in NxDb class Extract method
NxDbRow.cpp:NxDbRow::~NxDbRow()
NxDbRow.cpp:NxDbRow& NxDbRow::operator=(const NxDbRow& Other)
NxDbRow.cpp:void NxDbRow::Clear()
NxDbRow.cpp:unsigned char* NxDbRow::CreateRecord(string& strDbName,
NxDbRow.cpp:									 NxDb* pNxDb)
NxDbRow.cpp:	field* pField = pNxDb->GetField(strDbName);
NxDbRow.cpp:	int nRecSize = pNxDb->GetFilDes(strDbName)->recsiz;
NxDbRow.cpp:void NxDbRow::Export(vector<string>& vExportString)
NxDbRow.cpp:void NxDbRow::Import(const vector<string>& vExportString)
NxDbRow.cpp:bool NxDbRow::Save(const string& strDbName,
NxDbRow.cpp:				   NxDb* pNxDb)
NxDbRow.cpp:			pNxDb->DeleteRec(strName,m_nRecordNumber);
NxDbRow.cpp:			m_ucRecord=CreateRecord(strName,pNxDb);
NxDbRow.cpp:			pNxDb->Insert(strName,(char*)m_ucRecord);
NxDbRow.cpp:			m_ucRecord=CreateRecord(strName,pNxDb);
NxDbRow.cpp:			pNxDb->Edit(strName,m_nRecordNumber,(char*)m_ucRecord);
NxDbRow.cpp:bool NxDbRow::SetColumn(int nCol,
NxDbRow.cpp:bool NxDbRow::SetColumn(int nCol,
NxDbRow.cpp:void NxDbRow::SetColumns(field* pField)
NxDbRow.cpp:	NxDbColumn column(NxDbColumn::DataTypeChar);
NxDbRow.h:#include "NxDbColumn.h"
NxDbRow.h:class NxDbRow
NxDbRow.h:  public:NxDbRow();		// Default constructor
NxDbRow.h:    NxDbRow(field * pField);	// Construct with field definitions
NxDbRow.h:    NxDbRow(const string & strDbName,	// Construct from data base info
NxDbRow.h:	    int nRow, NxDb * pNxDb);
NxDbRow.h:    inline NxDbRow(const NxDbRow & Other)	// Copy constructor
NxDbRow.h:     ~NxDbRow();		// Destructor, closes the database
NxDbRow.h:    NxDbRow & operator=(const NxDbRow & Other);	// Assignment operator
NxDbRow.h:	      NxDb * pNxDb);
NxDbRow.h:    vector < NxDbColumn > m_vField;	// The fields in this row
NxDbRow.h:				NxDb * pNxDb);
NxDbRow.h:typedef vector < NxDbRow * >ROW_VECTOR;
OptionsDlg.cpp:			NxDbAccess::CloseAll();
PixilDTApp.cpp:	// Save the command line arguments for the NxDbAccess class
PixilDTApp.cpp:	NxDbAccess::SaveCmdLine(argc,argv);
PixilDT.dsp:SOURCE=.\NxDbAccess.cpp
PixilDT.dsp:SOURCE=.\NxDbColumn.cpp
PixilDT.dsp:SOURCE=.\NxDbRow.cpp
PixilDT.dsp:SOURCE=.\NxDbAccess.h
PixilDT.dsp:SOURCE=.\NxDbColumn.h
PixilDT.dsp:SOURCE=.\NxDbRow.h
PixilDT.dsw:Project: "NxDb"="..\NxDb\NxDb.dsp" - Package Owner=<4>
PixilDT.dsw:    Project_Dep_Name NxDb
PixilMainWnd.cpp:	NxDbAccess::DumpAll();
PixilMainWnd.cpp:	NxDbAccess::CloseAll();
SchedulerDB.cpp: : NxDbAccess("sched",&sFile,sFields)
SchedulerDB.cpp:	NxDbAccess::Delete(nRow);
SchedulerDB.cpp:	nRow=NxDbAccess::Import(vExportString);
SchedulerDB.cpp:	int nRow = NxDbAccess::Insert();
SchedulerDB.cpp:			NxDbAccess::Delete(nRow);
SchedulerDB.h:#include "NxDbAccess.h"
SchedulerDB.h:class SchedulerDB:public NxDbAccess
ToDoListDB.cpp: : NxDbAccess("td",&tdFile,tdFields)
ToDoListDB.cpp:	nRow=NxDbAccess::Import(vExportString);
ToDoListDB.cpp:  int nRow = NxDbAccess::Insert();
ToDoListDB.h:#include "NxDbAccess.h"
ToDoListDB.h:class ToDoListDB:public NxDbAccess
ToDoListList.cpp:bool ToDoListList::IsVisible(NxDbRow* pRow)
ToDoListList.cpp:bool ToDoListList::SortCompare(NxDbRow* pRow1,
ToDoListList.cpp:							   NxDbRow* pRow2)
ToDoListList.h:    bool IsVisible(NxDbRow * pRow);	// Test if a row is visible or not
ToDoListList.h:    static bool SortCompare(NxDbRow * pRow1,	// Sort by priority/due date
ToDoListList.h:			    NxDbRow * pRow2);

--- NEW FILE: Options.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Global application options.                                  //
//--------------------------------------------------------------//
#ifdef WIN32
#pragma warning(disable:4786)
#endif

#include <pwd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <map>
#include <string>
#include <vector>
#include <FL/fl_ask.H>
#include <FL/x.H>
#include "HelpID.h"
#include "IniDlg.h"
#include "Options.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#ifdef WIN32
#define strcasecmp stricmp	// MS Visual C renames this
#endif


using namespace std;


#ifndef WIN32_PROFILE_API
// Linux/Unix based INI file classes


//--------------------------------------------------------------//
// Class for individual INI file categories.                    //
//--------------------------------------------------------------//
class INICategory
{
  public:

    INICategory(const string & strName);	// Constructor

    inline INICategory(const INICategory & Other)	// Copy constructor
    {
	*this = Other;
    }

    INICategory & operator=(const INICategory & Other);	// Assignment operator

    bool operator==(const INICategory & Other) const;	// Comparison operator

    bool operator==(const string & strName) const;	// Comparison operator

    bool operator<(const INICategory & Other) const;	// Comparison operator

    inline const string & GetName() const	// Get the category name
    {
	return (m_strName);
    }

    string GetValue(const string & strName,	// Get the value of a setting
		    const string & strDefault);

    void SetOption(const string & strLine);	// Set a setting from "name=value"

    bool SetOption(const string & strName,	// Set a setting
		   const string & strValue);

    void Write(ostream & fileOut);	// Write this category to a stream


  private:

    map < string, string > m_mSetting;	// Settings for this category

    string m_strName;		// Name of this category

    map < string, string >::iterator FindSetting(const string & strValue);	// Find a setting

};


//--------------------------------------------------------------//
// Class to read and process an INI file.                       //
//--------------------------------------------------------------//
class INIFileReader
{
  public:

    INIFileReader(const string & strFileName);	// Construct from a file

      inline ~ INIFileReader()	// Destructor
    {
	Write();
    }

    string GetOption(const string & strCategory,	// Get an option from the file
		     const string & strName, const string & strDefault);

    void SetOption(const string & strCategory,	// Set an option in the file
		   const string & strName, const string & strValue);

    void Write();		// Write the INI file back to the file it was read from

    void Write(const string & strFileName);	// Write the INI file back to disk


  private:

    bool m_bModifiedFlag;	// Modified flag

    string m_strFileName;	// Name of the INI file

    vector < INICategory > m_vCategory;	// Categories in this INI file

    INICategory *FindCategory(const string & strCategory,	// Find or create a category
			      bool bCreate);

};


#endif


#ifdef WIN32
#define strcasecmp stricmp
#endif


//--------------------------------------------------------------//
// Singleton pointer.                                           //
//--------------------------------------------------------------//
Options *
    Options::m_pThis =
    NULL;


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
Options::Options()
{
    m_pThis = this;

#ifndef WIN32_PROFILE_API	// Linux/Unix only code

    // Read in the INI file
    SetIniFileName();
    m_pINIFileReader = new INIFileReader(m_strIniFile);

#endif
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
Options::~Options()
{
#ifndef WIN32_PROFILE_API

    // Write out the INI file
    delete((INIFileReader *) m_pINIFileReader);

#endif
}


//--------------------------------------------------------------//
// Destroy the Options object.                                  //
//--------------------------------------------------------------//
void
Options::Destroy()
{
    delete m_pThis;
    m_pThis = NULL;
}


//--------------------------------------------------------------//
// Get a boolean value from the INI file                        //
//--------------------------------------------------------------//
bool
Options::GetBooleanValue(const char *pszSection,
			 const char *pszSetting, bool bDefault)
{
    bool bReturn;
    string strValue;

#ifndef WIN32_PROFILE_API

    // Unix/Linux variation
    strValue =
	((INIFileReader *) (m_pThis->m_pINIFileReader))->GetOption(pszSection,
								   pszSetting,
								   "false");

#else

    char szValue[32];

    // Get the INI file name
    SetIniFileName();

    // Windows variation, get from the INI file
    ::GetPrivateProfileString(pszSection,
			      pszSetting,
			      "*",
			      szValue,
			      sizeof(szValue), m_pThis->m_strIniFile.c_str());
    strValue = szValue;

#endif

    if (strcasecmp(strValue.c_str(), "yes") == 0
	|| strcasecmp(strValue.c_str(), "true") == 0) {
	bReturn = true;
    } else if (strcmp(strValue.c_str(), "*") == 0) {
	bReturn = bDefault;
    } else {
	bReturn = false;
    }

    return (bReturn);
}


//--------------------------------------------------------------//
// Get an integer value from the INI file                       //
//--------------------------------------------------------------//
int
Options::GetIntValue(const char *pszSection, const char *pszSetting)
{
    int nReturn;
    string strValue;

#ifndef WIN32_PROFILE_API

    // Unix/Linux variation
    strValue =
	((INIFileReader *) (m_pThis->m_pINIFileReader))->GetOption(pszSection,
								   pszSetting,
								   "0");

#else

    char szValue[32];

    // Get the INI file name
    SetIniFileName();

    // Windows variation, get from the INI file
    ::GetPrivateProfileString(pszSection,
			      pszSetting,
			      "0",
			      szValue,
			      sizeof(szValue), m_pThis->m_strIniFile.c_str());
    strValue = szValue;

#endif

    nReturn = atoi(strValue.c_str());

    return (nReturn);
}


//--------------------------------------------------------------//
// Get a string value from the INI file                         //
//--------------------------------------------------------------//
string
Options::GetStringValue(const char *pszSection,
			const char *pszSetting, const char *pszDefault)
{
    string strValue;

#ifndef WIN32_PROFILE_API

    // Unix/Linux variation
    strValue =
	((INIFileReader *) (m_pThis->m_pINIFileReader))->GetOption(pszSection,
								   pszSetting,
								   pszDefault);

#else

    char szValue[512];

    // Get the INI file name
    SetIniFileName();

    // Windows variation, get from the INI file
    ::GetPrivateProfileString(pszSection,
			      pszSetting,
			      pszDefault,
			      szValue,
			      sizeof(szValue), m_pThis->m_strIniFile.c_str());
    strValue = szValue;

#endif

    return (strValue);
}


//--------------------------------------------------------------//
// Set a boolean value into the INI file                        //
//--------------------------------------------------------------//
void
Options::SetBooleanValue(const char *pszSection,
			 const char *pszSetting, bool bValue)
{
    const char *pszValue = (bValue == true ? "Yes" : "No");


#ifndef WIN32_PROFILE_API

    // Unix/Linux variation
    ((INIFileReader *) (m_pThis->m_pINIFileReader))->SetOption(pszSection,
							       pszSetting,
							       pszValue);

#else

    // Get the INI file name
    SetIniFileName();

    // Windows variation, save it
    ::WritePrivateProfileString(pszSection,
				pszSetting,
				pszValue, m_pThis->m_strIniFile.c_str());

#endif

}


//--------------------------------------------------------------//
// Set the name of the INI file.                                //
//--------------------------------------------------------------//
void
Options::SetIniFileName()
{
    if (m_pThis->m_strIniFile.length() == 0) {

#ifndef WIN32

	/* Linux */
	/* See if this user already has an INI file.  If so, use that */
	/* Otherwise, load the default ini file, and write it to the home directory */

	struct passwd *pwd = getpwuid(getuid());

	m_pThis->m_UserIniFile = 0;

	if (pwd) {
	    char path[128];
	    snprintf(path, 128, "%s/.pixildt/PixilDT.ini", pwd->pw_dir);

	    if (!access(path, F_OK)) {
		m_pThis->m_strIniFile = path;
		m_pThis->m_UserIniFile = 1;
		printf("Using INI file %s\n", path);
	    }
	}

	if (!m_pThis->m_UserIniFile) {
	    printf("Using the default INI file\n");
	    m_pThis->m_strIniFile = "./PixilDT.ini";
	}
#else

	char *pszPath;
	HKEY hKey;
	HKEY hKey2;
	HKEY hKey3;
	HKEY hKey4;
	unsigned long dwDisposition;
	unsigned long dwSize;
	unsigned long dwType;
	string strPath;

	// Get the INI file name from the registry if it is there
	if (::RegOpenKeyEx(HKEY_CURRENT_USER,
			   "Software\\Century Software\\Pixil Desktop",
			   0, KEY_READ, &hKey) == ERROR_SUCCESS) {
	    // Get the INI file path
	    if (::RegQueryValueEx(hKey,
				  "INIFile",
				  NULL,
				  &dwType, NULL, &dwSize) == ERROR_SUCCESS) {
		// Get the actual path data
		pszPath = new char[dwSize];
		::RegQueryValueEx(hKey,
				  "INIFile",
				  NULL,
				  &dwType,
				  (unsigned char *) pszPath, &dwSize);
		m_pThis->m_strIniFile = pszPath;
		delete[]pszPath;
	    }

	    ::RegCloseKey(hKey);
	}

	if (m_pThis->m_strIniFile.length() == 0) {
	    IniDlg *pDlg;

	    // No INI file available in the registry,
	    // Ask the user where to put the file
	    pDlg = new IniDlg();
	    if (pDlg->DoModal() != 1) {
		// Just quit if the user does not want to enter a directory for the files
		exit(EXIT_FAILURE);
	    }
	    strPath = pDlg->GetDataPath();
	    m_pThis->m_strIniFile = strPath;
	    if (m_pThis->m_strIniFile.length() == 0) {
		// Just quit if the user does not want to enter a directory for the files
		exit(EXIT_FAILURE);
	    }
	    m_pThis->m_strIniFile += "\\PixilDT.ini";
	    delete pDlg;

	    // Set the data base path
	    SetDatabasePath(strPath.c_str());

	    // Create these keys if they don't already exist
	    if (::RegCreateKeyEx(HKEY_CURRENT_USER,
				 "Software",
				 0,
				 NULL,
				 REG_OPTION_NON_VOLATILE,
				 KEY_WRITE,
				 NULL,
				 &hKey2, &dwDisposition) == ERROR_SUCCESS) {
		if (::RegCreateKeyEx(hKey2,
				     "Century Software",
				     0,
				     NULL,
				     REG_OPTION_NON_VOLATILE,
				     KEY_WRITE,
				     NULL,
				     &hKey3,
				     &dwDisposition) == ERROR_SUCCESS) {
		    if (::RegCreateKeyEx(hKey3,
					 "Pixil Desktop",
					 0,
					 NULL,
					 REG_OPTION_NON_VOLATILE,
					 KEY_WRITE,
					 NULL,
					 &hKey4,
					 &dwDisposition) == ERROR_SUCCESS) {
			// Set the INI file path
			long x =::RegSetValueEx(hKey4,
						"INIFile",
						NULL,
						REG_SZ,
						(const unsigned char
						 *) (m_pThis->m_strIniFile.
						     c_str()),
						m_pThis->m_strIniFile.
						length());
			::RegCloseKey(hKey4);
		    }
		    ::RegCloseKey(hKey3);
		}
		::RegCloseKey(hKey2);
	    }
	}
#endif

    }
}


//--------------------------------------------------------------//
// Set an integer value into the INI file                       //
//--------------------------------------------------------------//
void
Options::SetIntValue(const char *pszSection,
		     const char *pszSetting, int nValue)
{
    char szValue[16];

    // Get the value of the setting
    sprintf(szValue, "%d", nValue);

#ifndef WIN32_PROFILE_API

    // Unix/Linux variation
    ((INIFileReader *) (m_pThis->m_pINIFileReader))->SetOption(pszSection,
							       pszSetting,
							       szValue);

#else

    // Get the INI file name
    SetIniFileName();

    // Windows variation, save it
    ::WritePrivateProfileString(pszSection,
				pszSetting,
				szValue, m_pThis->m_strIniFile.c_str());

#endif

}


//--------------------------------------------------------------//
// Set astring value into the INI file                          //
//--------------------------------------------------------------//
void
Options::SetStringValue(const char *pszSection,
			const char *pszSetting, const char *pszValue)
{

#ifndef WIN32_PROFILE_API

    // Unix/Linux variation
    ((INIFileReader *) (m_pThis->m_pINIFileReader))->SetOption(pszSection,
							       pszSetting,
							       pszValue);

#else

    // Get the INI file name
    SetIniFileName();

    // Windows variation, save it
    ::WritePrivateProfileString(pszSection,
				pszSetting,
				pszValue, m_pThis->m_strIniFile.c_str());

#endif

}


#ifndef WIN32_PROFILE_API
// Linux/Unix based INI file classes


//--------------------------------------------------------------//
// Construct from an INI file.                                  //
//--------------------------------------------------------------//
INIFileReader::INIFileReader(const string & strFileName)
{
    char szBuffer[512];
    ifstream fileIn;
    INICategory *pINICategory = NULL;
    int i;
    string strName = "(none)";

    // Initialize instance variables
    m_bModifiedFlag = false;
    m_strFileName = strFileName;

    // Open the INI file
    fileIn.open(m_strFileName.c_str());

    // Continue if the file was found
    if (fileIn.is_open()) {
	// Read each line from the file
	while (!fileIn.eof()) {
	    fileIn.getline(szBuffer, sizeof(szBuffer));

	    // Trim trailing spaces from the line
	    i = strlen(szBuffer) - 1;
	    while (i >= 0 && isspace(szBuffer[i])) {
		szBuffer[i--] = '\0';
	    }

	    // Process the line if not blank
	    if (szBuffer[0] != '\0') {
		if (szBuffer[0] == '[') {
		    // New category, get the category name
		    strName = &szBuffer[1];
		    if (strName[strName.length() - 1] == ']') {
			strName = strName.substr(0, strName.length() - 1);
		    }
		    // Create the new category
		    FindCategory(strName, true);
		} else {
		    // This is a new option for the category
		    pINICategory = FindCategory(strName, true);

		    // Add this option to the category
		    pINICategory->SetOption(string(szBuffer));
		}
	    }
	}
    }
    // Reset the modified flag
    m_bModifiedFlag = false;

    // Clean up
    fileIn.close();
}


//--------------------------------------------------------------//
// Find a category or create one.                               //
//--------------------------------------------------------------//
INICategory *
INIFileReader::FindCategory(const string & strCategory, bool bCreate)
{
    bool bFound = false;
    INICategory *pINICategory = NULL;
    int i;
    int nMax = m_vCategory.size();

    // Find this category
    for (i = 0; i < nMax; ++i) {
	if (m_vCategory[i] == strCategory) {
	    pINICategory = &m_vCategory[i];
	    bFound = true;
	    break;
	}
    }

    // Was it found ?
    if (bFound == false && bCreate == true) {
	// Create a new one
	pINICategory = new INICategory(strCategory);
	m_vCategory.push_back(*pINICategory);
	delete pINICategory;
	pINICategory = &m_vCategory[m_vCategory.size() - 1];
	m_bModifiedFlag = true;
    }

    return (pINICategory);
}


//--------------------------------------------------------------//
// Retrieve an INI file setting.                                //
//--------------------------------------------------------------//
string
INIFileReader::GetOption(const string & strCategory,
			 const string & strName, const string & strDefault)
{
    INICategory *pINICategory = FindCategory(strCategory, false);
    string strReturn;

    if (pINICategory != NULL) {
	strReturn = pINICategory->GetValue(strName, strDefault);
    } else {
	strReturn = strDefault;
    }

    return (strReturn);
}


//--------------------------------------------------------------//
// Set or create an option.                                     //
//--------------------------------------------------------------//
void
INIFileReader::SetOption(const string & strCategory,
			 const string & strName, const string & strValue)
{
    bool bModifiedFlag;
    INICategory *pINICategory = FindCategory(strCategory, true);

    bModifiedFlag = pINICategory->SetOption(strName, strValue);
    if (bModifiedFlag == true) {
	m_bModifiedFlag = true;
    }
}


//--------------------------------------------------------------//
// Write the INI file back to disk overwriting the file it was  //
// read from.                                                   //
//--------------------------------------------------------------//
void
INIFileReader::Write()
{
    if (m_bModifiedFlag == true) {
	struct passwd *pwd = getpwuid(getuid());
	if (!pwd) {
	    printf("Error - unable to get the user name for id %d\n",
		   getuid());
	    return;
	}

	/* Create the user ini file if we need to */

	if (strncmp(pwd->pw_dir, m_strFileName.c_str(), strlen(pwd->pw_dir))) {
	    char path[128];
	    snprintf(path, 128, "%s/.pixildt", pwd->pw_dir);

	    if (access(path, F_OK)) {
		if (mkdir(path, 0755)) {
		    printf("Error - unable to create %s\n", path);
		    return;
		}
	    }

	    strcat(path, "/PixilDT.ini");
	    m_strFileName = path;

	    printf("Saving INI file %s\n", path);
	}


	Write(m_strFileName);
	m_bModifiedFlag = false;
    }
}


//--------------------------------------------------------------//
// Write the INI file back to disk.                             //
//--------------------------------------------------------------//
void
INIFileReader::Write(const string & strFileName)
{
    ofstream fileOut;
    vector < INICategory >::iterator iter;

    // Open the output file
    fileOut.open(strFileName.c_str());

    // Continue if open
    if (fileOut.is_open()) {
	for (iter = m_vCategory.begin(); iter != m_vCategory.end(); ++iter) {
	    iter->Write(fileOut);
	}
	fileOut.close();
    }
}


//--------------------------------------------------------------//
// Constructor.                                                 //
//--------------------------------------------------------------//
INICategory::INICategory(const string & strName)
{
    m_strName = strName;
}


//--------------------------------------------------------------//
// Assignment operator.                                         //
//--------------------------------------------------------------//
INICategory & INICategory::operator=(const INICategory & Other)
{
    m_mSetting = Other.m_mSetting;
    m_strName = Other.m_strName;
    return (*this);
}


//--------------------------------------------------------------//
// Comparison operator.                                         //
//--------------------------------------------------------------//
bool
INICategory::operator==(const INICategory & Other) const
{
    return (strcasecmp(m_strName.c_str(), Other.m_strName.c_str()) == 0);
}


//--------------------------------------------------------------//
// Comparison operator.                                         //
//--------------------------------------------------------------//
bool
INICategory::operator==(const string & strOther) const
{
    return (strcasecmp(m_strName.c_str(), strOther.c_str()) == 0);
}


//--------------------------------------------------------------//
// Comparison operator.                                         //
//--------------------------------------------------------------//
bool
INICategory::operator<(const INICategory & Other) const
{
    return (strcasecmp(m_strName.c_str(), Other.m_strName.c_str()) < 0);
}


//--------------------------------------------------------------//
// Find a setting by name                                       //
//--------------------------------------------------------------//
map < string,
    string >::iterator INICategory::FindSetting(const string & strName)
{
    map < string, string >::iterator iter;

    for (iter = m_mSetting.begin(); iter != m_mSetting.end(); ++iter) {
	if (strcasecmp(strName.c_str(), iter->first.c_str()) == 0) {
	    break;
	}
    }
    return (iter);
}


//--------------------------------------------------------------//
// Get the value for a name                                     //
//--------------------------------------------------------------//
string
INICategory::GetValue(const string & strName, const string & strDefault)
{
    map < string, string >::iterator iter = FindSetting(strName);
    string strReturn;

    if (iter != m_mSetting.end()) {
	strReturn = iter->second;
    } else {
	strReturn = strDefault;
    }
    return (strReturn);
}


//--------------------------------------------------------------//
// Add an option from a string in the format name=value.        //
//--------------------------------------------------------------//
void
INICategory::SetOption(const string & strLine)
{
    string strName;
    string strValue;
    unsigned int nPos;

    // Get the option name and value from the string
    nPos = strLine.find("=");
    if (nPos >= 0) {
	// Get the name
	if (nPos > 0) {
	    strName = strLine.substr(0, nPos);
	} else {
	    strName = "";
	}

	// Get the value
	if (nPos < strLine.length() - 1) {
	    strValue = strLine.substr(nPos + 1, strLine.length());
	} else {
	    strValue = "";
	}
    } else {
	// No equal sign, assume all is name
	strName = strLine;
	strValue = "";
    }

    SetOption(strName, strValue);
}


//--------------------------------------------------------------//
// Set or create an option.                                     //
//--------------------------------------------------------------//
bool
INICategory::SetOption(const string & strName, const string & strValue)
{
    bool bReturn = true;
    map < string, string >::iterator iter;
    pair < string, string > prElement;

    // Is the name in the list
    iter = FindSetting(strName);

    if (iter == m_mSetting.end()) {
	// Name not found, create it
	prElement.first = strName;
	prElement.second = strValue;
	m_mSetting.insert(prElement);
    } else if (iter->second != strValue) {
	// Different value, set to the new one
	iter->second = strValue;
    } else {
	// Same value, no need to set
	bReturn = false;
    }

    return (bReturn);
}


//--------------------------------------------------------------//
// Write this category to disk.                                 //
//--------------------------------------------------------------//
void
INICategory::Write(ostream & fileOut)
{
    map < string, string >::iterator iter;

    // Output the category name
    fileOut << "[" << m_strName.c_str()
	<< "]" << endl;

    // Output the values within
    for (iter = m_mSetting.begin(); iter != m_mSetting.end(); ++iter) {
	fileOut << iter->first.c_str()
	    << "=" << iter->second.c_str()
	    << endl;
    }

    // Output a blank line
    fileOut << endl;
}


#endif

--- NEW FILE: ToDoListDetails.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the ToDo List Details.                             //
//--------------------------------------------------------------//
#ifndef TODOLISTDETAILS_H_

#define TODOLISTDETAILS_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Multiline_Input.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Pixmap.H>
#include "Messages.h"
class ToDoListDetails:public Fl_Group
{
  public:ToDoListDetails(int nX,
		    // Constructor
		    int nY, int nWidth, int nHeight);
     ~ToDoListDetails();	// Destructor
    void ChangeComplete(int nRow,	// The completed flag has been changed in the list, change in the details
			int nComplete);
    void ChangeTime(int nRow,	// The due date/date completed has been changed in the list, change in the details
		    time_t nTime);
    void DisplayRow(int nRow,	// Display a ToDo item
		    int nRows);
    void Enable(bool bEnable);	// Enable or disable all input in the details
    int Message(PixilDTMessage nMessage,	// Process a message from the parent widget
		int nInfo);
    int SaveChanges(bool bAsk);	// Save any changes to disk
  private:char m_szLabel[5][2];
    // Labels for the priority radio buttons
    Fl_Button *m_pApplyButton;	// The Apply button
    Fl_Button *m_pDateButton;	// The date picker button
    Fl_Button *m_pNoteButton;	// The Note button
    Fl_Button *m_pPriority[5];	// Priority radio buttons
    Fl_Check_Button *m_pCompleteButton;	// The complete check box
    Fl_Choice *m_pCategoryChoice;	// The category choice
    Fl_Input *m_pDate;		// The date due/completed
    Fl_Multiline_Input *m_pTitle;	// The Title
    Fl_Menu_Item *m_pCategoryMenu;	// Category choice menu
    Fl_Output *m_pDayOfWeek;	// The day of week for the due date
    Fl_Output *m_pDesc;		// The note description
    Fl_Pixmap *m_pCalendarPixmap;	// The date picker button image
    Fl_Pixmap *m_pNotePixmap;	// The Notes/Description button image
    int m_nID;			// The ToDo item's ID being displayed
    time_t m_nDate;		// The current due/complete date
    static void DateButtonCallback(Fl_Widget * pWidget,	// Date button callback
				   void *pUserData);
    static void NoteButtonCallback(Fl_Widget * pWidget,	// Note/Description button callback
				   void *pUserData);
    static void OnApply(Fl_Widget * pWidget,	// Process an apply button click
			void *pUserData);
    bool ProcessDate();		// Process a newly entered date
};


#endif /*  */

--- NEW FILE: SchedulerDB.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler database definition fields.                        //
//--------------------------------------------------------------//
#include "config.h"
#include <ctime>
#include "SchedulerDB.h"
#include "SchedulerDBDef.h"
#include "TimeFunc.h"

#include "FLTKUtil.h"
#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Pointer to the only one of these objects.                    //
//--------------------------------------------------------------//
SchedulerDB *
    SchedulerDB::m_pThis =
    NULL;


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
SchedulerDB::SchedulerDB()
:  NxDbAccess("sched", &sFile, sFields)
{
    bool bGood;
    int nRecno;
    int nRow;
    int nRow2;
    int nMax = NumRecs();

    // Examine the data base for bad exception record pointers
    for (nRow = 0; nRow < nMax; ++nRow) {
	// Process if this is an exception row
	if (!IsDeleted(nRow)) {
	    if (IsException(nRow)) {
		// Reset this flag
		bGood = true;

		// Find the parent repeating event
		nRecno = GetExceptionRecno(nRow);
		nRow2 = FindRow(SCHED_ID, nRecno);
		if (nRow2 < 0) {
		    // Exception for non-existent repeating event
		    bGood = false;
		} else if (GetRepeatFlag1(nRow2) == REPEAT_NONE) {
		    // Exception to a non-repeating event
		    bGood = false;
		}
		// Is this a bad row
		if (bGood == false) {
#ifdef DEBUG
		    assert(false);	// Bad exception row
#endif

		    // Delete this row
		    Delete(nRow);
		}
	    }
	}
    }
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
SchedulerDB::~SchedulerDB()
{
    m_pThis = NULL;
}


//--------------------------------------------------------------//
// Add a deleted exception row for a given root row and a       //
// selected date.                                               //
//--------------------------------------------------------------//
void
SchedulerDB::AddDeletedException(int nRow, time_t nDate)
{
    int nRowNew = Insert();
    time_t nTime;

#ifdef DEBUG
    assert(::NormalizeDate(nDate) == nDate);	// Date must be normalized
#endif

    // Set every field of the deleted exception
    nTime = GetStartTime(nRow);
    SetStartTime(nRowNew, nDate + (nTime -::NormalizeDate(nTime)));
    nTime = GetEndTime(nRow);
    SetEndTime(nRowNew, nDate + (nTime -::NormalizeDate(nTime)));
    SetAllDayFlag(nRowNew, 0);
    SetRepeatFlag1(nRowNew, 0);
    SetRepeatFlag2(nRowNew, 0);
    SetRepeatFlag3(nRowNew, 0);
    SetRepeatWeekMonth(nRowNew, 0);
    SetEntryType(nRowNew, 0);
    SetDescription(nRowNew, "");
    SetExceptionFlag(nRowNew, SCHED_EXCEPTION + SCHED_DELETED_EXCEPTION);
    SetExceptionRecno(nRowNew, GetID(nRow));
    SetAlarmInterval(nRowNew, 0);
    SetAlarmFlags(nRowNew, SCHED_NO_ALARM);
}


//--------------------------------------------------------------//
// Make a copy of a row.                                        //
//--------------------------------------------------------------//
int
SchedulerDB::CopyRow(int nRow)
{
    int nNewRow = Insert();

    SetCategory(nNewRow, GetCategory(nRow));
    SetStartTime(nNewRow, GetStartTime(nRow));
    SetEndTime(nNewRow, GetEndTime(nRow));
    SetAllDayFlag(nNewRow, GetAllDayFlag(nRow));
    SetRepeatFlag1(nNewRow, GetRepeatFlag1(nRow));
    SetRepeatFlag2(nNewRow, GetRepeatFlag2(nRow));
    SetRepeatFlag3(nNewRow, GetRepeatFlag3(nRow));
    SetRepeatWeekMonth(nNewRow, GetRepeatWeekMonth(nRow));
    SetEntryType(nNewRow, GetEntryType(nRow));
    SetDescription(nNewRow, GetDescription(nRow).c_str());
    SetExceptionFlag(nNewRow, GetExceptionFlag(nRow));
    SetExceptionRecno(nNewRow, GetExceptionRecno(nRow));
    SetAlarmInterval(nNewRow, GetAlarmInterval(nRow));
    SetAlarmFlags(nNewRow, GetAlarmFlags(nRow));

    return (nNewRow);
}


//--------------------------------------------------------------//
// Delete a row and all exceptions for the row.                 //
//--------------------------------------------------------------//
void
SchedulerDB::Delete(int nRow)
{
    // Delete the row
    NxDbAccess::Delete(nRow);

    // Delete all exceptions for this row
    RemoveExceptions(nRow);
}


//--------------------------------------------------------------//
// Set the ending date for a repeating event.                   //
//--------------------------------------------------------------//
void
SchedulerDB::EndRepetitions(int nRow, time_t nDate)
{
#ifdef DEBUG
    assert(nDate == 0 || nDate ==::NormalizeDate(nDate));	// The date must be normalized
#endif

    if (nDate == 0) {
	// Set no end date
	SetRepeatFlag3(nRow, 0);
    } else if (nDate < GetStartTime(nRow)) {
	// If ending prior to the start time then delete this event
	Delete(nRow);
    } else {
	// Set the ending date
	SetRepeatFlag3(nRow,::AddDays(nDate, 1) - 1);
    }
}


//--------------------------------------------------------------//
// Get all events for a given day.  The multimap will be        //
// returned as an array of row numbers that represent events    //
// for this date.                                               //
//--------------------------------------------------------------//
int
SchedulerDB::GetAllAppointments(time_t nDate, multimap < int, int >&mRecord)
{
    bool bRemove;
    int nKey;
    int nMax = NumRecs();
    int nRow;
    SchedulerRepeatData *pSchedulerRepeatData;
    time_t nEndTime;
    time_t nStartTime;

#ifdef DEBUG
    assert(nDate == NormalizeDate(nDate));	// Must be a "normalized" date (midnight)
#endif

    // Clear the vector
    mRecord.clear();

    // Process each row in the data base
    for (nRow = 0; nRow < nMax; ++nRow) {
	if (!IsDeleted(nRow) && !IsDeletedException(nRow)) {
	    pSchedulerRepeatData = GetSchedulerRepeatData(nRow);
	    if (pSchedulerRepeatData->IsOnDay(nDate) == true) {
		// Test for a deleted exception to a repeating event
		bRemove = false;
		if (GetRepeatFlag1(nRow) != REPEAT_NONE) {
		    if (HasDeletedException(nRow, nDate)) {
			bRemove = true;
		    }
		}
		// Add only if not deleted
		if (bRemove == false) {
		    // Get the appointment times
		    nStartTime = GetStartTime(nRow);
		    nEndTime = GetEndTime(nRow);

		    // Set up a key and add it to the map of events
		    nKey =
			1440 * ((nStartTime -::NormalizeDate(nStartTime)) /
				60)
			+ ((nEndTime -::NormalizeDate(nEndTime)) / 60);
		    mRecord.insert(make_pair(nKey, nRow));
		}
	    }
	    delete pSchedulerRepeatData;
	}
    }

    return (mRecord.size());
}


//--------------------------------------------------------------//
// Get all events for a range of days.                          //
//--------------------------------------------------------------//
void
SchedulerDB::GetEvents(multimap < int, int >*pmEvent, time_t nDate, int nDays)
{
    bool bRemove;
    int i;
    int nKey;
    int nMax = NumRecs();
    int nRow;
    SchedulerRepeatData *pSchedulerRepeatData;
    time_t nEndTime;
    time_t nStartTime;
    time_t nTime;

    // Clear out the older events
    for (i = 0; i < nDays; ++i) {
	pmEvent[i].clear();
    }

    // Look at each event
    for (nRow = 0; nRow < nMax; ++nRow) {
	if (!IsDeleted(nRow)
	    && !IsDeletedException(nRow)) {
	    // Get the repetition parameters
	    pSchedulerRepeatData = GetSchedulerRepeatData(nRow);

	    // Test each day in turn
	    for (i = 0; i < nDays; ++i) {
		nTime =::AddDays(nDate, i);
		if (pSchedulerRepeatData->IsOnDay(nTime) == true) {
		    // Test if this event has been removed via a repeating exception
		    bRemove = false;
		    if (GetRepeatFlag1(nRow) != REPEAT_NONE) {
			if (HasDeletedException(nRow, nTime)) {
			    bRemove = true;
			}
		    }
		    // Add only if not deleted
		    if (bRemove == false) {
			// Get the start and end times
			nStartTime = GetStartTime(nRow);
			nEndTime = GetEndTime(nRow);

			// Add this event to the map of events
			nKey =
			    1440 *
			    ((nStartTime -::NormalizeDate(nStartTime)) / 60)
			    + ((nEndTime -::NormalizeDate(nEndTime)) / 60);
			pmEvent[i].insert(make_pair(nKey, nRow));
		    }
		}
	    }

	    // Clean up after this event
	    delete pSchedulerRepeatData;
	}
    }
}


//--------------------------------------------------------------//
// Get the repeat type (repeat flag 1) as a string.             //
//--------------------------------------------------------------//
const char *
SchedulerDB::GetRepeatTypeString(int nRepeatType)
{
    static const char *pszRepeatType[5] = {
	N_("None"),
	N_("Daily"),
	N_("Weekly"),
	N_("Monthly"),
	N_("Yearly"),
    };
    int nIndex;

    switch (nRepeatType) {
    case REPEAT_NONE:
	nIndex = 0;
	break;

    case REPEAT_DAILY:
	nIndex = 1;
	break;

    case REPEAT_WEEKLY:
	nIndex = 2;
	break;

    case REPEAT_MONTHLY:
	nIndex = 3;
	break;

    case REPEAT_YEARLY:
	nIndex = 4;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown repeat type
#endif
	nIndex = 0;		// Call it not repeating
    }
    return (_(pszRepeatType[nIndex]));
}


//--------------------------------------------------------------//
// Get a pointer to an open data base.                          //
//--------------------------------------------------------------//
SchedulerDB *
SchedulerDB::GetSchedulerDB()
{
    if (m_pThis == NULL) {
	m_pThis = new SchedulerDB;
    }
    return (m_pThis);
}


//--------------------------------------------------------------//
// Get the repeat settings.                                     //
//--------------------------------------------------------------//
SchedulerRepeatData *
SchedulerDB::GetSchedulerRepeatData(int nRow) const
{
    return (new SchedulerRepeatData(GetStartTime(nRow),
				    GetEndTime(nRow),
				    GetRepeatFlag1(nRow),
				    GetRepeatFlag2(nRow),
				    GetRepeatFlag3(nRow),
				    GetRepeatWeekMonth(nRow)));
}


//--------------------------------------------------------------//
// Get the start time as a string.                              //
//--------------------------------------------------------------//
string
SchedulerDB::GetStartTimeString(int nRow) const
{
    string strTime;
    time_t nTime = GetStartTime(nRow);

    strTime =::FormatTime(nTime);
    return (strTime);
}


//--------------------------------------------------------------//
// Get indications of which days have scheduled events.         //
// Assumes that pbEvent point to an array of at least 366       //
// bools.                                                       //
//--------------------------------------------------------------//
void
SchedulerDB::GetYearlyEvents(bool * pbEvent, int nYear)
{
    int nMax = NumRecs();
    int nRow;
    SchedulerRepeatData *pSchedulerRepeatData;

    // Clear the old event indications
    memset(pbEvent, 0, 366 * sizeof(bool));

    // Examine each event
    for (nRow = 0; nRow < nMax; ++nRow) {
	if (!IsDeleted(nRow)) {
	    pSchedulerRepeatData = GetSchedulerRepeatData(nRow);
	    pSchedulerRepeatData->GetYearlyEvents(pbEvent, nYear);
	    delete pSchedulerRepeatData;
	}
    }
}


//--------------------------------------------------------------//
// Test whether this row has a deleted exception for a given    //
// date or not.                                                 //
//--------------------------------------------------------------//
bool
SchedulerDB::HasDeletedException(int nRow, time_t nDate)
{
    bool bReturn = false;
    int i;
    int nID = GetID(nRow);
    int nMax = NumRecs();

#ifdef DEBUG
    assert(GetRepeatFlag1(nRow) != REPEAT_NONE);	// Must be a repeating event
#endif

    // Find an exception for this row
    for (i = 0; i < nMax && bReturn == false; ++i) {
	// Only examine non-deleted rows
	if (!IsDeleted(i)) {
	    // Only look further at deleted exception rows
	    if (IsDeletedException(i)) {
		// Find exceptions to this row
		if (GetExceptionRecno(i) == nID) {
		    // Is it for this day
		    if (::NormalizeDate(GetStartTime(i)) == nDate) {
			bReturn = true;
		    }
		}
	    }
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Import a row from a set of strings.                          //
//--------------------------------------------------------------//
int
SchedulerDB::Import(const vector < string > &vExportString)
{
    int nRow;

    // Import the data
    nRow = NxDbAccess::Import(vExportString);

    // Now fix the record number
    SetColumn(nRow, SCHED_ID, 0);
    SetHighStringKey(nRow, SCHED_ID);

    return (nRow);
}


//--------------------------------------------------------------//
// Insert a new row and set its key id.                         //
//--------------------------------------------------------------//
int
SchedulerDB::Insert()
{
    int nRow = NxDbAccess::Insert();

    // Turn off any alarms
    SetAlarmFlags(nRow, SCHED_NO_ALARM);

    // Now set a unique key value
    SetHighKey(nRow, SCHED_ID);

    return (nRow);
}


//--------------------------------------------------------------//
// Move an event to a new time (with the same duration).        //
//--------------------------------------------------------------//
bool
SchedulerDB::MoveStartTime(int nRow, int nSeconds)
{
    bool bReturn;
    int nChange;
    time_t nStartDate =::NormalizeDate(GetStartTime(nRow));
    time_t nTime;

#ifdef DEBUG
    assert(nSeconds >= 0 && nSeconds < 24 * 60 * 60);	// Movement amount must be in range
#endif

    // Calculate the change in the start time
    nChange = nSeconds - GetStartTime(nRow) + nStartDate;

    // Change the start time
    nTime = nStartDate + nSeconds;

    // Correct for a daylight savings time shift
    while (::NormalizeDate(nTime) != nStartDate) {
	// Reduce it one hour
	nTime -= 60 * 60;
    }

    // Set the new start time
    bReturn = (nTime != GetStartTime(nRow));
    SetStartTime(nRow, nTime);

    // Change the end time
    nTime =
	((GetEndTime(nRow) - nStartDate + nChange) % (24 * 60 * 60)) +
	nStartDate;
    if (nTime < GetStartTime(nRow)) {
	nTime = 24 * 60 * 60 - 1 + nStartDate;
    }
    // Correct for a daylight savings time shift
    while (::NormalizeDate(nTime) != nStartDate) {
	// Reduce it one hour
	nTime -= 60 * 60;
    }

    // Set the new end time
    bReturn |= (nTime != GetEndTime(nRow));
    SetEndTime(nRow, nTime);

    return (bReturn);
}


//--------------------------------------------------------------//
// Remove all exceptons for a row.                              //
//--------------------------------------------------------------//
void
SchedulerDB::RemoveExceptions(int nRow)
{
    int nID = GetID(nRow);
    int nMax = NumRecs();

    // Delete all exceptions for this row
    for (nRow = 0; nRow < nMax; ++nRow) {
	if (!IsDeleted(nRow)
	    && IsException(nRow)
	    && GetExceptionRecno(nRow) == nID) {
	    NxDbAccess::Delete(nRow);
	}
    }
}


//--------------------------------------------------------------//
// Test if this repeat data is different from a row.            //
//--------------------------------------------------------------//
bool
SchedulerDB::RepeatDataChanged(int nRow, SchedulerRepeatData * pRepeatData)
{
    bool bReturn;
    SchedulerRepeatData *pRepeatData2 = GetSchedulerRepeatData(nRow);

    bReturn = (*pRepeatData2 == *pRepeatData);
    delete pRepeatData2;
    return (bReturn);
}


//--------------------------------------------------------------//
// Set that this event does not repeat.                         //
//--------------------------------------------------------------//
void
SchedulerDB::SetNoRepetition(int nRow)
{
    SetRepeatFlag1(nRow, 0);
    SetRepeatFlag2(nRow, 0);
    SetRepeatFlag3(nRow, 0);
    SetRepeatWeekMonth(nRow, 0);
}


//--------------------------------------------------------------//
// Set the duration to some number of seconds, but then change  //
// the end-time to the nearest half-hour.                       //
//--------------------------------------------------------------//
bool
SchedulerDB::SetRoundedDuration(int nRow, int nSeconds)
{
    bool bReturn;
    time_t nEndTime;
    struct tm *pTm;

    nEndTime = GetStartTime(nRow) + nSeconds;
    pTm = localtime(&nEndTime);
    nSeconds = pTm->tm_hour * 60 * 60 + pTm->tm_min * 60 + pTm->tm_sec;
    nSeconds = 30 * 60 * ((nSeconds + 15 * 60 - 1) / (30 * 60));
    if (nSeconds >= 24 * 60 * 60) {
	nSeconds = 24 * 60 * 60 - 1;
    }
    pTm->tm_sec = (nSeconds % (60 * 60));
    pTm->tm_min = ((nSeconds / 60) % 60);
    pTm->tm_hour = nSeconds / (60 * 60);
    nEndTime = mktime(pTm);
    if (nEndTime != GetEndTime(nRow)) {
	SetEndTime(nRow, nEndTime);
	bReturn = true;
    } else {
	bReturn = false;
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Set the repeat settings, the start and end times are not     //
// changed here.                                                //
//--------------------------------------------------------------//
void
SchedulerDB::SetSchedulerRepeatData(int nRow,
				    const SchedulerRepeatData *
				    pSchedulerRepeatData)
{
    SetRepeatFlag1(nRow, pSchedulerRepeatData->GetRepeatFlag1());
    SetRepeatFlag2(nRow, pSchedulerRepeatData->GetRepeatFlag2());
    SetRepeatFlag3(nRow, pSchedulerRepeatData->GetRepeatFlag3());
    SetRepeatWeekMonth(nRow, pSchedulerRepeatData->GetRepeatWeekMonth());
}


//--------------------------------------------------------------//
// Used when dragging an event to a new time.  This will set    //
// the start time as per the arguments given and then set the   //
// end time for the same duration.                              //
//--------------------------------------------------------------//
void
SchedulerDB::SetStartDate(int nRow, time_t nDate, int nTime)
{
    int nDuration = GetEndTime(nRow) - GetStartTime(nRow);
    time_t nNewTime;

#ifdef DEBUG
    assert(nDate ==::NormalizeDate(nDate));	// The date must be normalized
#endif

    // Set the start time
    nNewTime = nDate + nTime;
    if (::NormalizeDate(nNewTime) != nDate) {
	// Fix if spans midnight
	nNewTime =::AddDays(nDate, 1) - 5 * 60;
    }
    SetStartTime(nRow, nNewTime);

    // Now set the end time
    nNewTime = nDate + nTime + nDuration;
    if (::NormalizeDate(nNewTime) != nDate) {
	// Fix if spans midnight
	nNewTime =::AddDays(nDate, 1) - 1;
    }
    SetEndTime(nRow, nNewTime);
}

--- NEW FILE: HelpID.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Help ID's passed back to the main application.               //
//--------------------------------------------------------------//
#ifndef HELPID_H_

#define HELPID_H_
enum HelpID
{ HELP_NO_TOPIC = 0,		// No topic specified
    HELP_ADDRESS_BOOK_CATEGORY,	// Help on address book categories
    HELP_ADDRESS_BOOK_DLG,	// Help on the Address Book update dialog
    HELP_CATEGORY_EDITOR,	// Help on the Category Editor
    HELP_CUSTOM_FIELD_EDITOR,	// Help on the Custom Field Editor
    HELP_FIND_DLG,		// Help on the Find dialog
    HELP_LISTBY_DLG,		// Help on the Address Book/List By dialog
    HELP_NEW_USER,		// Help for the new user dialog
    HELP_NOTES_CATEGORY,	// Help on notes categories
    HELP_NOTE_EDITOR_DLG,	// Help on the Note Editor dialog
    HELP_OPTIONS_DLG,		// Help on the Options dialog
    HELP_SCHEDULER_CATEGORY,	// Help on scheduler categories
    HELP_SCHEDULER_DLG,		// Help on the Scheduler update dialog
    HELP_SCHEDULER_REPEAT_DLG,	// Help on the Scheduler Repeat entry dialog
    HELP_SCHEDULER_TIME_DLG,	// Help on the Scheduler time entry dialog
    HELP_TODO_LIST_CATEGORY,	// Help on ToDO list categories
    HELP_TODO_SHOW_DLG,		// Help on the ToDo List Show dialog
};

#endif /*  */

--- NEW FILE: FLTKUtil.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// FLTK utilities                                               //
//--------------------------------------------------------------//
#ifndef FLTKUTIL_H_

#define FLTKUTIL_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <string>
#include <utility>
#include <vector>
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Window.H>
using namespace std;
void BreakLines(const char *pszString,	// Break a string into lines delimited by new line characters
		vector < string > &vLine);
Fl_Menu_Item *CreateChoice(int nCount,	// Create a translated menu for an Fl_Choice
			   const char *const *ppszText, bool bTranslateMenu);
int DoModal(Fl_Window * pWindow,	// Run a modal dialog
	    Fl_Button * pOKButton, Fl_Button * pCancelButton);
int DoPopupMenu(const Fl_Menu_Item * pMenuItem,	// Show a popup menu
		int nX, int nY);
void FreeTranslatedMenu(Fl_Menu_Item * pMenuItem);	// Free a menu created by TranslateMenuItems
Fl_Color GetFLTKColor(int nRGB);	// Get an FLTK color
Fl_Color GetFLTKColor(int nRed, int nGreen, int nBlue);	// Get an FLTK color
void SetBackgroundColor();	// Set the window backgound color (FL_GRAY)
Fl_Menu_Item *TranslateMenuItems(const Fl_Menu_Item * pMenu_Item);	// Translate text in a set of const menu items
Fl_Menu_Item *TranslateMenuItems(Fl_Menu_Item * pMenu_Item);	// Translate text in a set of non-const menu items
string WrapText(const char *pszText,	// Get the first part of a line of text
		int nMaxWidth, Fl_Widget * pWidget);

// WIN32 debugging routines
#ifdef WIN32
#ifdef _DEBUG
extern "C"
{
    __declspec(dllimport) void __stdcall OutputDebugStringA(const char
							    *pOutputString);
}

#define OutputDebugString  OutputDebugStringA

#endif				// _DEBUG
#endif				// WIN32

#endif				/*  */

--- NEW FILE: NoteList.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the Notes List.                                    //
//--------------------------------------------------------------//
#include "config.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "Images.h"
#include "NoteList.h"
#include "Notes.h"
#include "NotesCategoryDB.h"
#include "PixilDT.h"
#include "Printer.h"

#include "VCMemoryLeak.h"

#ifdef WIN32
#define strcasecmp stricmp
#endif


//--------------------------------------------------------------//
// Icon column indicators                                       //
//--------------------------------------------------------------//
const bool
    NoteList::m_bIconColumns[2] = {
	true,
false };


//--------------------------------------------------------------//
// Category currently being filtered for                        //
//--------------------------------------------------------------//
int
    NoteList::m_nSortCategory;


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
NoteList::NoteList(int nX, int nY, int nWidth, int nHeight)
    :
TableBase(nX, nY, nWidth, nHeight)
{
    m_nCategory = -1;		// Select all categories

    // Create the notes icon
    m_pNotesIcon = Images::GetNotesIcon();

    // Finish TableBase construction
    PostConstructor(NoteDB::GetNoteDB()->NumUndeletedRecs(), 2,	// 2 columns
		    m_bIconColumns);

    // Display the details for the first line if it exists
    if (rows() > 0) {
	row(0);
	Refresh();
	SelectRow(0);
    }
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
NoteList::~NoteList()
{
    delete m_pNotesIcon;
}


//--------------------------------------------------------------//
// Recalculate column widths                                    //
//--------------------------------------------------------------//
void
NoteList::CalculateColumnWidths(int nWidth)
{
    m_nColWidth[0] = 12;	// An icon
    m_nColWidth[1] = nWidth - 12;	// All but one icons
}


//--------------------------------------------------------------//
// Process a double click over a row (do nothing)               //
//--------------------------------------------------------------//
void
NoteList::DoubleClick(int nRow, int nCol)
{
}


//--------------------------------------------------------------//
// Filter the displayed rows by category (-1 = all categories)  //
//--------------------------------------------------------------//
void
NoteList::Filter(int nCategory)
{
    // Convert the category row to a category key
    if (nCategory != -1) {
	nCategory =
	    NotesCategoryDB::GetNotesCategoryDB()->GetCategoryID(nCategory);
    }
    // Sort the rows in the database by category
    m_nCategory = nCategory;

    // Go refresh (and actually do the sort)
    Refresh();
}


//--------------------------------------------------------------//
// Get the icon for an icon column                              //
//--------------------------------------------------------------//
Fl_Pixmap *
NoteList::GetIconValue(int nRow, int nCol)
{
    Fl_Pixmap *pPixmap;

    switch (nCol) {
    case 0:			// Always gets a Notes icon
	pPixmap = m_pNotesIcon;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Should not get here for some other column
#endif
	;
    }
    return (pPixmap);
}


//--------------------------------------------------------------//
// Get the value of a column.                                   //
//--------------------------------------------------------------//
string
NoteList::GetStringValue(int nRow, int nCol)
{
    string strData;

    switch (nCol) {
    case 1:			// First part of the notes text
	strData =::WrapText(NoteDB::GetNoteDB()->GetTitle(nRow).c_str(),
			    m_nColWidth[1] - DLG_BORDER, this);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Should not get here for some other column
#endif
	;
    }
    return (strData);
}

//--------------------------------------------------------------//
// Process a left mouse click over an icon, same as over        //
// anywhere else.                                               //
//--------------------------------------------------------------//
void
NoteList::IconClick(int nRow, int nCol)
{
    LeftClick(nRow, nCol);
}


//--------------------------------------------------------------//
// Process a left mouse click over a non-icon column.           //
//--------------------------------------------------------------//
void
NoteList::LeftClick(int nRow, int nCol)
{
    SelectRow(nRow);
}


//--------------------------------------------------------------//
// Process a message from the parent widget                     //
//--------------------------------------------------------------//
int
NoteList::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case NOTES_CHANGED:
	Refresh();
	break;

    case NOTES_GOTO:		// Find dialog requested a note
	{
	    int nCount;
	    int nRow;
	    NoteDB *pNoteDB = NoteDB::GetNoteDB();

	    // Is this item visible ?
	    nRow = pNoteDB->FindPhysicalRecord(nInfo);
	    nCount = pNoteDB->NumRecsByKey(NOTE_CAT, m_nCategory);
	    if (nRow >= nCount) {
		// Show all categories so this row can be seen
		m_nCategory = -1;

		// Refresh for this row
		Refresh(pNoteDB->GetIndex(nRow));
	    } else {
		// The row is visible, just select it
		SelectRow(nRow);
	    }
	}
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Print the notes.                                             //
//--------------------------------------------------------------//
void
NoteList::Print()
{
    int nBorder = INCH / 2;	// 1/2 inch border
    int nCopy;
    const int nFontSize = 10;
    int nRow;
    int nRows;
    Note *pNote;
    NoteDB *pNoteDB = NoteDB::GetNoteDB();
    Printer printer;

    // Save any changes
    ((Notes *) parent())->SaveDetailChanges();

    // Open the printer
    if (printer.Open(_("Notes")) == true) {
	// Set an hourglass cursor
	PixilDT::GetApp()->GetMainWindow()->SetCursor(FL_CURSOR_WAIT);

	// Print once for eqch requested copy
	for (nCopy = 0; nCopy < printer.GetCopies(); ++nCopy) {
	    // Reset the page number
	    printer.ResetPageNumber();

	    // Go to two column mode
	    printer.SetSerifFont(nFontSize);
	    printer.SetTwoColumnMode(425 * INCH / 100 - 2 * nBorder,
				     nBorder, _("Notes"), NULL, 184);

	    // Print each visible entry
	    if (m_nCategory == -1) {
		// Show all rows
		nRows = pNoteDB->NumUndeletedRecs();
	    } else {
		// Filter by category
		nRows = pNoteDB->NumRecsByKey(NOTE_INDEX, m_nCategory);
	    }

	    // Print each row
	    for (nRow = 0; nRow < nRows; ++nRow) {
		// Output a blank line if needed
		if (nRow != 0) {
		    printer.ColumnNewLine();
		}
		// Output the note title
		printer.SetBoldSerifFont(nFontSize);
		printer.ColumnShow(pNoteDB->GetTitle(nRow).c_str(), 0, 0);
		printer.SetSerifFont(nFontSize);

		// Output the category
		printer.ColumnShowNoAdvance(_("Category:"), INCH / 4);
		printer.ColumnShow(pNoteDB->GetCategoryName(nRow).c_str(),
				   (9 * INCH) / 8, 0);

		// Output the note
		pNote = pNoteDB->GetNote(nRow);
		if (pNote->GetText().length() > 0) {
		    printer.ColumnShow(pNote->GetText().c_str(), INCH / 4, 0);
		}
		delete pNote;
	    }

	    // End the page
	    printer.EndTwoColumnMode();
	}

	// All done, close the printer
	printer.Close();

	// Reset the cursor
	PixilDT::GetApp()->GetMainWindow()->ResetCursor();
    }
}


//--------------------------------------------------------------//
// Refresh this list                                            //
//--------------------------------------------------------------//
void
NoteList::Refresh(int nID)
{
    int nRow = row();
    int nRows;
    NoteDB *pNoteDB = NoteDB::GetNoteDB();


    // Get the currently selected row
    if (nID < 0) {
	if (nRow >= 0 && pNoteDB->NumUndeletedRecs() > 0) {
	    nID = pNoteDB->GetIndex(nRow);
	} else {
	    // No row currently selected
	    nID = -1;
	}
    }
    // Re-sort the data base
    if (m_nCategory == -1) {
	// Sort for all categories
	pNoteDB->Sort(SortCompare);
	nRows = pNoteDB->NumUndeletedRecs();
    } else {
	// Filter by category
	m_nSortCategory = m_nCategory;
	pNoteDB->Sort(SortCategory);
	nRows = pNoteDB->NumRecsByKey(NOTE_CAT, m_nCategory);
    }
    row(-1);			// Workaround for top_row update
    rows(nRows);

#if 0				// These buttons are non-functional so far (08/06/01)
    // Enable/Disable the Cut/Copy toolbar items
    PixilDT::GetApp()->GetMainWindow()->Notify(row >=
					       0 ? ENABLE_TOOLBAR_BUTTON :
					       DISABLE_TOOLBAR_BUTTON,
					       EDITCUT_ICON);
    PixilDT::GetApp()->GetMainWindow()->Notify(row >=
					       0 ? ENABLE_TOOLBAR_BUTTON :
					       DISABLE_TOOLBAR_BUTTON,
					       EDITCOPY_ICON);
#endif

    // Reselect the same row if possible
    nRow = pNoteDB->FindRow(NOTE_INDEX, nID);
    if (nRow >= 0) {
	// See if visible based on selected category
	if (m_nCategory != -1) {
	    if (nRow >= pNoteDB->NumRecsByKey(NOTE_CAT, m_nCategory)) {
		// Not visible, reselect row 0
		nRow = 0;
	    }
	}
    } else {
	nRow = 0;
    }
    row(nRow);

    // Cause the list to be redrawn
    redraw();
    SelectRow(nRows > 0 ? row() : -1);
}


//--------------------------------------------------------------//
// Process a right mouse click anywhere.                        //
//--------------------------------------------------------------//
void
NoteList::RightClick(int nRow, int nCol)
{
    static const Fl_Menu_Item menuPopup1[] = {
	{N_("Delete Note"),},
	{N_("Copy Note"),},
	{N_("Cut Note"), 0, 0, 0, FL_MENU_DIVIDER},
	{N_("New Note"),},
	{N_("Paste Note"),},
	{NULL},
    };
    static const Fl_Menu_Item menuPopup2[] = {
	{N_("Delete Note"),},
	{N_("Copy Note"),},
	{N_("Cut Note"), 0, 0, 0, FL_MENU_DIVIDER},
	{N_("New Note"),},
	{NULL},
    };
    const Fl_Menu_Item *pmenuPopup;
    int nSelection;

    // Only ask whether to save the pending detail changes if not clicking on a row
    if (nRow < 0) {
	((Notes *) parent())->SaveDetailChanges();
    }
    // Display the details for this line to the right
    SelectRow(nRow);

    // Display the popup menu
    pmenuPopup = ((Notes *) parent())->CanPaste()
	? menuPopup1 : menuPopup2;
    nSelection = DoPopupMenu((nRow >= 0 ? pmenuPopup : &pmenuPopup[3]),
			     Fl::event_x(), Fl::event_y());

    if (nSelection >= 0) {
	// Correct for no delete row option
	nSelection += (nRow < 0 ? 3 : 0);

	switch (nSelection) {
	case 0:		// Delete this row
	    ((Notes *) parent())->Delete(nRow);
	    break;

	case 1:		// Copy this row
	    ((Notes *) parent())->Copy(nRow);
	    break;

	case 2:		// Cut this row
	    ((Notes *) parent())->Cut(nRow);
	    break;

	case 3:		// Insert a new row
	    ((Notes *) parent())->EditNew();
	    break;

	case 4:		// Paste a row
	    ((Notes *) parent())->Paste();
	}
    }
}


//--------------------------------------------------------------//
// Select a row in the list and inform the parent of the        //
// selection                                                    //
//--------------------------------------------------------------//
void
NoteList::SelectRow(int nRow)
{
    if (nRow >= 0) {
	row(nRow);
	((Notes *) parent())->DisplayRow(nRow);
    }
}


//--------------------------------------------------------------//
// Compare by note title and filter by category for sorting.    //
//--------------------------------------------------------------//
bool
NoteList::SortCategory(NxDbRow * pRow1, NxDbRow * pRow2)
{
    bool bReturn;

    // Is the first row the correct category
    if (pRow1->GetIntValue(NOTE_CAT) == m_nSortCategory) {
	// Is the second row the correct category
	if (pRow2->GetIntValue(NOTE_CAT) == m_nSortCategory) {
	    // Both good, sort like normal
	    bReturn = SortCompare(pRow1, pRow2);
	} else {
	    // First is good, second is not, say first is lower
	    bReturn = true;
	}
    } else {
	// Is the second row the correct category
	if (pRow2->GetIntValue(NOTE_CAT) == m_nSortCategory) {
	    // First is not good, second is good, say first is not lower
	    bReturn = false;
	} else {
	    // Both not good, sort like normal
	    bReturn = SortCompare(pRow1, pRow2);
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Compare by note title for sorting.                           //
//--------------------------------------------------------------//
bool
NoteList::SortCompare(NxDbRow * pRow1, NxDbRow * pRow2)
{
    bool bReturn;
    string strString1 = pRow1->GetStringValue(NOTE_DESC);
    string strString2 = pRow2->GetStringValue(NOTE_DESC);

    if (strcasecmp(strString1.c_str(), strString2.c_str()) < 0) {
	bReturn = true;
    } else {
	bReturn = false;
    }
    return (bReturn);
}

--- NEW FILE: SchedulerDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler database class.                                    //
//--------------------------------------------------------------//
#ifndef SCHEDULERDB_H_

#define SCHEDULERDB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <map>
#include <string>
#include <vector>
#include "NxDbAccess.h"
using namespace std;

//--------------------------------------------------------------//
// (08/15/2001) - There have been some discrepancies in the     //
// written documentation about the contents of the Scheduler    //
// data base fields. Here is what this class uses for each      //
// field:                                                       //
//                                                              //
// ID - database assigned ID number, unique to all rows in the  //
//      data base, but not necessarily equal to the physical    //
//      row number.                                             //
// Category - not used, always 0.                               //
// Start Time - the number of seconds (time_t value) for the    //
//      start time of the appointment.                          //
// End Time - the number of seconds (time_t value) for the end  //
//      time of the appointment.                                //
// All Day Flag - a value of 1 can indicate that the            //
//      appointment spans more than one day or lasts until the  //
//      end of the day.  This is not currently implemented, so  //
//      this field is always zero.                              //
// Repeat Flag 1 - indicates whether the appointment repeats or //
//      not, see the defines below.                             //
// Repeat Flag 2 - indicates the number of units between each   //
//      repetition of an event.  Example: a 2 here for a daily  //
//      event indicates that the event occurs every 2 days.     //
// Repeat Flag 3 - (as of 08/22/2001) the end date of the       //
//      repetition (as a time_t data type) or a zero if there   //
//      is no end date.                                         //
//      (Up until 08/22/2001 this had been the number of times  //
//      that an event will repeat.  The bits 0xf000 must be on  //
//      if there is an end time for the repetition.  If these   //
//      bits are on then the bits in the 0x0fff position of the //
//      field contain a repeat count.  The end repetition date  //
//      can be calculated useing the start time and the repeat  //
//      count.  The bits 0xffff0000 are not used.)              //
//                                                              //
// Weekly/Monthly Repeat Flag - contains more information about //
//      how a weekly or monthly repetition should occur.  For a //
//      weekly repetition, this contains bits for each day of   //
//      the week on which the event should occur.  For a        //
//      monthly repetition, there are two different bits which  //
//      indicate whether an event should occur on the same day  //
//      of month or on the same day-of-week and week of the     //
//      month.  For example, a month event can repeat on the    //
//      tenth of the month or on the second Tuesday of the      //
//      month.                                                  //
// Entry Type - indicates whether the event is an appointment   //
//      or a task.  Zero for an appointment or 1 for a task.    //
//      Currently not implemented, will always be zero.         //
// Description - the description of the event.                  //
//                                                              //
// 10/11/2001 - next update:                                    //
//                                                              //
// Exception Flag - This flag has two documented values.        //
//      SCHED_EXCEPTION was to be used to denote that the       //
//      record represents an override to a repetition of a      //
//      repeating event.  SCHED_DELETED_EXCEPTION indicates     //
//      that this is a repetition of a repeating event that     //
//      will not occur.  As per word-of-mouth, the              //
//      SCHED_EXCEPTION bit is not to be used on its own but    //
//      only in conjunction with the SCHED_DELETED_EXCEPTION    //
//      setting - a row must have both or neither of these on.  //
//      When a single instance of a repetition is to be         //
//      changed, the original will be deleted with a            //
//      SCHED_DELETED_EXCEPTION row (and the other bit as well) //
//      and then a new event will be added as a normal          //
//      appointment.                                            //
// Recno Pointer - for a row with the SCHED_EXCEPTION setting   //
//      in the exception flag, this will be the record number   //
//      (RECNO key value) of the original repeating row from    //
//      which the current row is an exception.                  //
// Alarm Interval - a value from 0 through 99 indicating the    //
//      number of time units prior to the event to sound an     //
//      alarm.  The Alarm Flags field will indicate whether     //
//      this event should have an alarm or not.                 //
// Alarm Flags - indicates what type of time units are used for //
//      the alarm interval.  See below for the actual values.   //
//                                                              //
// 10/12/2001 - More verbal specs:                              //
//   1) A deleted exception cannot be deleted by the user.      //
//      That means that once a user has changed a subsequent    //
//      repetition of an event causing a deleted exception and  //
//      a new normal event to be inserted into the data base,   //
//      the user cannot revert to the data base prior to the    //
//      change.                                                 //
//   2) Palm Desktop has what seems to be a bug - taking a      //
//      repeating event and changing the way in which it        //
//      repeats (weekly to monthly repetition) and requesting   //
//      that all events be changed will not change events prior //
//      to the date of the event selected for editing.          //
//      According to the Scheduler written for the PDA this     //
//      should change every event even in the past.             //
//   3) Changing only the description of an event should not    //
//      cause the dialog about changing all or only one event   //
//      to appear.  This should change the root record for the  //
//      repetition.                                             //
//--------------------------------------------------------------//

// Field References
#define SCHED_ID                0
#define SCHED_CAT               1
#define SCHED_START_TIME        2
#define SCHED_END_TIME          3
#define SCHED_ALL_DAY_FLAG      4
#define SCHED_REPEAT_FLAG_1     5
#define SCHED_REPEAT_FLAG_2     6
#define SCHED_REPEAT_FLAG_3     7
#define SCHED_REPEAT_WEEK_MONTH 8
#define SCHED_ENTRY_TYPE        9
#define SCHED_DESC             10
#define SCHED_EXCEPTION_FLAG   11
#define SCHED_RECNO_POINTER    12
#define SCHED_ALARM_INTERVAL   13
#define SCHED_ALARM_FLAGS      14
#define SCHED_NUM_FIELDS       13

#define SCHED_DESC_LEN 100

// These flags are kept in Repeat_Flag_1
#define REPEAT_NONE           0x0000
#define REPEAT_DAILY          0x0001
#define REPEAT_WEEKLY         0x0002
#define REPEAT_MONTHLY        0x0004
#define REPEAT_YEARLY         0x0008

// These flags are kept in Week_Month_Repeat_Flag
#define REPEAT_WEEK_SUNDAY    0x0001
#define REPEAT_WEEK_MONDAY    0x0002
#define REPEAT_WEEK_TUESDAY   0x0004
#define REPEAT_WEEK_WEDNESDAY 0x0008
#define REPEAT_WEEK_THURSDAY  0x0010
#define REPEAT_WEEK_FRIDAY    0x0020
#define REPEAT_WEEK_SATURDAY  0x0040
#define REPEAT_WEEK_FLAGS     0x007f

#define REPEAT_MONTH_DAY      0x0080
#define REPEAT_MONTH_DATE     0x0100

// These flags are kept in Exception
#define SCHED_EXCEPTION       0x0001
#define SCHED_DELETED_EXCEPTION 0x0002

// These flags are kept in Alarm Flags
#define SCHED_ALARM_MINUTES   0x0000
#define SCHED_ALARM_HOURS     0x0001
#define SCHED_ALARM_DAYS      0x0002
#define SCHED_NO_ALARM        ((signed short)0xffff)	// Treated as a -1

// Include this after the above includes
#include "SchedulerRepeatData.h"

#define SCHED_NOTES_PREFIX "scd_"
class SchedulerDB:public NxDbAccess
{
  public:SchedulerDB();	// Constructor
    ~SchedulerDB();		// Destructor
    void AddDeletedException(int nRow,	// Add a deleted exception for a given date
			     time_t nDate);
    int CopyRow(int nRow);	// Insert a new row exactly like the given row
    void Delete(int nRow);	// Delete a row and all exceptions for it
    void EndRepetitions(int nRow,	// End repetitions on a given date
			time_t nDate);
    inline int GetAlarmFlags(int nRow)	// Get the alarm flags
    {
	return (GetIntValue(nRow, SCHED_ALARM_FLAGS));
    }
    inline int GetAlarmInterval(int nRow)	// Get the minutes/hours/days prior for the alarm
    {
	return (GetIntValue(nRow, SCHED_ALARM_INTERVAL));
    }
    int GetAllAppointments(time_t nDate,	// Get an array of physical record numbers that are events for the day
			   multimap < int, int >&mRecord);
    inline int GetAllDayFlag(int nRow) const	// Get the all day flag
    {
	return (GetIntValue(nRow, SCHED_ALL_DAY_FLAG));
    }
    inline int GetCategory(int nRow) const	// Get the Category
    {
	return (GetIntValue(nRow, SCHED_CAT));
    }
    inline string GetDescription(int nRow) const	// Get the description
    {
	return (GetStringValue(nRow, SCHED_DESC));
    }
    inline int GetEndTime(int nRow) const	// Get the end time
    {
	return (GetIntValue(nRow, SCHED_END_TIME));
    }
    inline int GetEntryType(int nRow) const	// Get the entry type
    {
	return (GetIntValue(nRow, SCHED_ENTRY_TYPE));
    }
    void GetEvents(multimap < int, int >*pmEvent,	// Get all events for a range of days
		   time_t nDate, int nDays);
    inline int GetExceptionFlag(int nRow)	// Get the exception flag
    {
	return (GetIntValue(nRow, SCHED_EXCEPTION_FLAG));
    }
    inline int GetExceptionRecno(int nRow)	// Get the exception record number
    {
	return (GetIntValue(nRow, SCHED_RECNO_POINTER));
    }
    inline int GetID(int nRow) const	// Get the ID
    {
	return (GetIntValue(nRow, SCHED_ID));
    }
    inline bool GetRepeatingFlag(int nRow) const	// Get whether this event is a repeating event (or exception to a repeating event)
    {
	return ((GetIntValue(nRow, SCHED_REPEAT_FLAG_1) &
		 (REPEAT_DAILY | REPEAT_WEEKLY | REPEAT_MONTHLY |
		  REPEAT_YEARLY)) || (GetIntValue(nRow,
						  SCHED_EXCEPTION_FLAG) &
				      (SCHED_EXCEPTION |
				       SCHED_DELETED_EXCEPTION)));
    }
    inline int GetRepeatType(int nRow)	// Get the repeat type for a row
    {
	return (GetRepeatFlag1(nRow));
    }
    static const char *GetRepeatTypeString(int nRepeatType);	// Get the repeat type as a string
    static SchedulerDB *GetSchedulerDB();	// Get the singleton pointer
    SchedulerRepeatData *GetSchedulerRepeatData(int nRow) const;	// Get the repetition settings
    inline int GetStartTime(int nRow) const	// Get the start time
    {
	return (GetIntValue(nRow, SCHED_START_TIME));
    }
    string GetStartTimeString(int nRow) const;	// Get the start time as a string
    void GetYearlyEvents(bool * pEvent,	// Get flags for whether any day of the year has an event
			 int nYear);
    int Import(const vector < string > &strData);	// Import a delimited string
    int Insert();		// Insert a row and set its key value
    inline bool IsDeletedException(int nRow)	// Is this row a deleted exception
    {
	return ((GetExceptionFlag(nRow) & SCHED_DELETED_EXCEPTION) != 0);
    }
    inline bool IsException(int nRow)	// Is this row an exception
    {
	return ((GetExceptionFlag(nRow) & SCHED_EXCEPTION) != 0);
    }
    bool MoveStartTime(int nRow,	// Change the start and end times of an event
		       int nSeconds);
    void RemoveExceptions(int nRow);	// Remove all deleted exceptions related to a row
    bool RepeatDataChanged(int nRow,	// Test if the repeat data is different
			   SchedulerRepeatData * pRepeatData);
    inline void SetAlarmFlags(int nRow, int nFlags)	// Set the alarm flags
    {
	SetColumn(nRow, SCHED_ALARM_FLAGS, nFlags);
    }
    inline void SetAlarmInterval(int nRow, int nInterval)	// Set the minutes/hours/days prior for the alarm
    {
	SetColumn(nRow, SCHED_ALARM_INTERVAL, nInterval);
    }
    inline void SetAllDayFlag(int nRow, int nAllDayFlag)	// Set the all day flag
    {
	SetColumn(nRow, SCHED_ALL_DAY_FLAG, nAllDayFlag);
    }
    inline void SetCategory(int nRow, int nCategory)	// Set the Category
    {
	SetColumn(nRow, SCHED_CAT, nCategory);
    }
    inline void SetDescription(int nRow, const char *pszDesc)	// Set the description
    {
	SetColumn(nRow, SCHED_DESC, pszDesc);
    }
    inline void SetEndTime(int nRow, int nEndTime)	// Set the end time
    {
	SetColumn(nRow, SCHED_END_TIME, nEndTime);
    }
    inline void SetEntryType(int nRow, int nEntryType)	// Set the entry type
    {
	SetColumn(nRow, SCHED_ENTRY_TYPE, nEntryType);
    }
    inline void SetID(int nRow, int nID)	// Set the ID
    {
	SetColumn(nRow, SCHED_ID, nID);
    }
    void SetNoRepetition(int nRow);	// Set that this event does not repeat
    bool SetRoundedDuration(int nRow,	// Set the duration, but round the end to the nearest half hour
			    int nSeconds);
    void SetSchedulerRepeatData(int nRow,	// Set the repetition settings
				const SchedulerRepeatData *
				pSchedulerRepeatData);
    void SetStartDate(int nRow,	// Set the start date and move the end date to the same date
		      time_t nDate, int nTime);
    inline void SetStartTime(int nRow, int nStartTime)	// Set the start time
    {
	SetColumn(nRow, SCHED_START_TIME, nStartTime);
    }
  private:static SchedulerDB *m_pThis;
    // One and only object
    inline int GetRepeatFlag1(int nRow) const	// Get the first repeat flag
    {
	return (GetIntValue(nRow, SCHED_REPEAT_FLAG_1));
    }
    inline int GetRepeatFlag2(int nRow) const	// Get the second repeat flag
    {
	return (GetIntValue(nRow, SCHED_REPEAT_FLAG_2));
    }
    inline int GetRepeatFlag3(int nRow) const	// Get the third repeat flag
    {
	return (GetIntValue(nRow, SCHED_REPEAT_FLAG_3));
    }
    inline int GetRepeatWeekMonth(int nRow) const	// Get the repeat weekly/monthly flags
    {
	return (GetIntValue(nRow, SCHED_REPEAT_WEEK_MONTH));
    }
    bool HasDeletedException(int nRow,	// Test whether this row has a deleted exception for a given date
			     time_t nDate);
    inline void SetExceptionFlag(int nRow, int nException)	// Set the exception type
    {
	SetColumn(nRow, SCHED_EXCEPTION_FLAG, nException);
    }
    inline void SetExceptionRecno(int nRow, int nRecno)	// Set the exception parent record number
    {
	SetColumn(nRow, SCHED_RECNO_POINTER, nRecno);
    }
    inline void SetRepeatFlag1(int nRow, int nRepeatFlag1)	// Set the first repeat flag
    {
	SetColumn(nRow, SCHED_REPEAT_FLAG_1, nRepeatFlag1);
    }
    inline void SetRepeatFlag2(int nRow, int nRepeatFlag2)	// Set the second repeat flag
    {
	SetColumn(nRow, SCHED_REPEAT_FLAG_2, nRepeatFlag2);
    }
    inline void SetRepeatFlag3(int nRow, int nRepeatFlag3)	// Set the third repeat flag
    {
	SetColumn(nRow, SCHED_REPEAT_FLAG_3, nRepeatFlag3);
    }
    inline void SetRepeatWeekMonth(int nRow, int nRepeatWeekMonth)	// Set the repeat weekly/monthly flags
    {
	SetColumn(nRow, SCHED_REPEAT_WEEK_MONTH, nRepeatWeekMonth);
    }
};


#endif /*  */

--- NEW FILE: PixilDTApp.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Main routine for PixilDT prototype.                          //
//--------------------------------------------------------------//

#include <pixil_config.h>

#include "config.h"
#include <cstdlib>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>

#include "PixilDT.h"
#include "VCMemoryLeak.h"
#include "Sync.h"

#ifdef DEBUG
#ifdef WIN32
// For at exit memory leak detection
void CheckMemoryLeaks();
_CrtMemState MemState1;
#endif
#endif


int
main(int argc, char **argv)
{
    // Set up internationalization
#ifdef CONFIG_PIXILDT_INTERNATIONAL
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);
#endif

#ifdef DEBUG
#ifdef WIN32
    // Visual C memory leak detection
    atexit(CheckMemoryLeaks);
    _CrtMemCheckpoint(&MemState1);
#endif
#endif

#ifdef CONFIG_SYNC
    atexit(CloseSync);
#endif

    // Save the command line arguments for the NxDbAccess class
    NxDbAccess::SaveCmdLine(argc, argv);

    // Start the real stuff
    Fl::visual(FL_RGB);
    PixilDT App(argc, argv);

#ifdef CONFIG_SYNC
    if (InitSync() == -1)
	printf("Error - Unable to start up the sync app\n");
#endif

    Fl::run();

    return (EXIT_SUCCESS);
}


#ifdef DEBUG
#ifdef WIN32
extern "C"
{
    extern struct buffer *startbuf;
}
extern
//--------------------------------------------------------------//
// Visual C memory leak detection                               //
//--------------------------------------------------------------//
    void
CheckMemoryLeaks()
{
    // Clean up after code in blkio.c
    free(startbuf);

    // Clean up after code in fl_font.cxx
    //free(fl_fontsize);

    // Test for any memory leaks
    _CrtMemDumpAllObjectsSince(&MemState1);
}
#endif
#endif

--- NEW FILE: AddressBookDB.cpp ---
 /*                                                                       
  * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
  *                                                                       
  * This file is part of the PIXIL Operating Environment                 
  *                                                                       
  * The use, copying and distribution of this file is governed by one    
  * of two licenses, the PIXIL Commercial License, or the GNU General    
  * Public License, version 2.                                           
  *                                                                       
  * Licensees holding a valid PIXIL Commercial License may use this file 
  * in accordance with the PIXIL Commercial License Agreement provided   
  * with the Software. Others are governed under the terms of the GNU   
  * General Public License version 2.                                    
  *                                                                       
  * This file may be distributed and/or modified under the terms of the  
  * GNU General Public License version 2 as published by the Free        
  * Software Foundation and appearing in the file LICENSE.GPL included   
  * in the packaging of this file.                                      
  *                                                                       
  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
  * PARTICULAR PURPOSE.                                                  
  *                                                                       
  * RESTRICTED RIGHTS LEGEND                                             
  *                                                                     
  * Use, duplication, or disclosure by the government is subject to      
  * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
  * Technical Data and Computer Software clause in DAR 7-104.9(a).       
  *                                                                      
  * See http://www.pixil.org/gpl/ for GPL licensing       
  * information.                                                         
  *                                                                      
  * See http://www.pixil.org/license.html or              
  * email cetsales at centurysoftware.com for information about the PIXIL   
  * Commercial License Agreement, or if any conditions of this licensing 
  * are not clear to you.                                                
  */

 //--------------------------------------------------------------//
 // Address Book database definition fields.                     //
 //--------------------------------------------------------------//
#include "config.h"
#include "AddressBookCategoryDB.h"
#include "AddressBookDB.h"
#include "AddressBookDBDef.h"
#include "CustomFieldDB.h"

#include "VCMemoryLeak.h"


 //--------------------------------------------------------------//
 // Pointer to the only one of these objects.                    //
 //--------------------------------------------------------------//
AddressBookDB *
    AddressBookDB::m_pThis =
    NULL;


 //--------------------------------------------------------------//
 // Constructor                                                  //
 //--------------------------------------------------------------//
AddressBookDB::AddressBookDB()
:  NxDbAccess("add", &cFile, cFields)
{
    printf("ADDRESSBOOKDB:  Created (%x)\n", this);
}


 //--------------------------------------------------------------//
 // Destructor                                                   //
 //--------------------------------------------------------------//
AddressBookDB::~AddressBookDB()
{
    m_pThis = NULL;
}


 //--------------------------------------------------------------//
 // Delete an address line including deleting the note if any    //
 // exists.                                                      //
 //--------------------------------------------------------------//
void
AddressBookDB::Delete(int nRow)
{
    Note *pNote = GetNote(nRow);

    pNote->Delete();
    delete pNote;

    NxDbAccess::Delete(nRow);
}


 //--------------------------------------------------------------//
 // Export to a delimited string including the notes.            //
 //--------------------------------------------------------------//
void
AddressBookDB::Export(int nRow, vector < string > &vExportString)
{
    Note *pNote;

    // Export the data base record
    NxDbAccess::Export(nRow, vExportString);

    // Get the notes for this row
    pNote = GetNote(nRow);
    vExportString.push_back(pNote->GetText());
    delete pNote;
}


 //--------------------------------------------------------------//
 // Workaround for the RECNO column being a character string.    //
 //--------------------------------------------------------------//
int
AddressBookDB::FindRecno(int nRecno)
{
    char szRecno[16];

    sprintf(szRecno, "%d", nRecno);
    return (FindRow(AB_RECNO, szRecno));
}


 //--------------------------------------------------------------//
 // Get a pointer to an open data base.                          //
 //--------------------------------------------------------------//
AddressBookDB *
AddressBookDB::GetAddressBookDB()
{
    if (m_pThis == NULL) {
	m_pThis = new AddressBookDB;
    }
    return (m_pThis);
}


 //--------------------------------------------------------------//
 // Get the name of a category.                                  //
 //--------------------------------------------------------------//
string
AddressBookDB::GetCategoryName(int nRow) const
{
    AddressBookCategoryDB *pCategory =
	AddressBookCategoryDB::GetAddressBookCategoryDB();
    int nCategory = GetCategory(nRow);
    int nCategoryRow = pCategory->FindRow(CATID, nCategory);

    return (pCategory->GetCategory(nCategoryRow));
}


 //--------------------------------------------------------------//
 // Get the name of a custom field.                              //
 //--------------------------------------------------------------//
string
AddressBookDB::GetCustomFieldName(int nIndex) const
{
    CustomFieldDB *pCustomFieldDB = CustomFieldDB::GetCustomField();
    int nRow;

#ifdef DEBUG
    assert(nIndex >= 0 && nIndex < 4);
#endif

    nRow = pCustomFieldDB->FindRow(CUSTOMID, nIndex);
    return (pCustomFieldDB->GetName(nRow));
}


 //--------------------------------------------------------------//
 // Get the name of an Info field.                               //
 //--------------------------------------------------------------//
string
AddressBookDB::GetInfoName(int nIndex)
{
    InfoDB *pInfoDB = InfoDB::GetInfo();
    int nInfoRow = pInfoDB->FindRow(INFOID, nIndex);

    return (pInfoDB->GetInfoType(nInfoRow));
}


 //--------------------------------------------------------------//
 // Get the name of an Info field.                               //
 //--------------------------------------------------------------//
string
AddressBookDB::GetInfoName(int nRow, int nIndex) const
{
    int nNameIndex;

#ifdef DEBUG
    assert(nIndex >= 0 && nIndex < 7);
#endif

    nNameIndex = GetInfoID(nRow, nIndex);
    return (GetInfoName(nNameIndex));
}


 //--------------------------------------------------------------//
 // Get the notes for a row.                                     //
 //--------------------------------------------------------------//
Note *
AddressBookDB::GetNote(int nRow) const
{
    Note *pReturn;
    string strNoteFile = GetNoteFile(nRow);

    if (strNoteFile.length() == 0) {
	// No file name
	pReturn = new Note(0, ADDRESS_BOOK_NOTES_PREFIX);
    } else {
	// Already have a file
	pReturn = new Note(strNoteFile.c_str(), 0, ADDRESS_BOOK_NOTES_PREFIX);
    }
    return (pReturn);
}


 //--------------------------------------------------------------//
 // Import from a delimited string.                              //
 //--------------------------------------------------------------//
int
AddressBookDB::Import(const vector < string > &vExportString)
{
    int nRow;
    Note *pNote;
    string strNote;
    vector < string > vExportString2 = vExportString;

    // Save the last string as the notes for this row
    strNote = vExportString2[vExportString2.size() - 1];
    vExportString2.pop_back();

    // Import the data
    nRow = NxDbAccess::Import(vExportString2);

    // Create the note for this row
    pNote = new Note(0, ADDRESS_BOOK_NOTES_PREFIX);
    pNote->SetText(strNote.c_str());
    SetNote(nRow, pNote);
    delete pNote;

    // Now fix the record number
    SetStringValue(nRow, AB_RECNO, "0");
    SetHighStringKey(nRow, AB_RECNO);

    return (nRow);
}


 //--------------------------------------------------------------//
 // Insert a new row and set its key id.                         //
 //--------------------------------------------------------------//
int
AddressBookDB::Insert()
{
    printf("DEBUG (%x)->Insert()\n", this);
    int nRow = NxDbAccess::Insert();

    // Now set a unique key value
    //      SetHighStringKey(nRow,AB_RECNO);
    SetHighKey(nRow, AB_RECNO);

    return (nRow);
}


//--------------------------------------------------------------//
// Get the number of records for a category.                    //
//--------------------------------------------------------------//
int
AddressBookDB::NumRecsByCategory(int nCategory)
{
    char szCategory[16];

    sprintf(szCategory, "%d", nCategory);
    return (NumRecsByKey(AB_CAT, szCategory));
}


//--------------------------------------------------------------//
// Set the notes for this address book line.                    //
//--------------------------------------------------------------//
void
AddressBookDB::SetNote(int nRow, Note * pNote)
{
    // Save to set the file name
    pNote->Save();

    // Save the note file name
    SetNoteFile(nRow, pNote->GetFileName().c_str());
}

--- NEW FILE: SpinInput.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// A class for what looks like a spin control.                  //
//--------------------------------------------------------------//
#include <cstdio>
#include <FL/Fl.H>
#include <FL/Fl_Repeat_Button.H>
#include "Dialog.h"
#include "Images.h"
#include "SpinInput.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
SpinInput::SpinInput(int nX,
		     int nY,
		     int nWidth,
		     int nHeight,
		     const char *pszLabel,
		     int nMaxSize, int nMinimum, int nMaximum)
    :
Fl_Group(nX, nY, nWidth, nHeight)
{
    Fl_Repeat_Button *pButton;

    // Create what looks like a spin control with some surrounding text
    m_pInput =
	new Fl_Int_Input(nX, nY, nWidth - IMAGE_BUTTON_WIDTH, nHeight,
			 pszLabel);
    m_pInput->maximum_size(nMaxSize);
    m_nMin = nMinimum;
    if (nMaximum > nMinimum) {
	m_nMax = nMaximum;
    } else {
	m_nMax = m_nMin;
    }
    if (m_nMin > 0) {
	value(m_nMin);
    } else if (m_nMax < 0) {
	value(m_nMax);
    } else {
	value(0);
    }
    pButton = new Fl_Repeat_Button(nX + nWidth - IMAGE_BUTTON_WIDTH,
				   nY, IMAGE_BUTTON_WIDTH, nHeight / 2);
    pButton->callback(OnUpButton);
    m_pUpPixmap = Images::GetSmallUpIcon();
    m_pUpPixmap->label(pButton);
    pButton = new Fl_Repeat_Button(nX + nWidth - IMAGE_BUTTON_WIDTH,
				   nY + nHeight / 2,
				   IMAGE_BUTTON_WIDTH, nHeight - nHeight / 2);
    pButton->callback(OnDownButton);
    m_pDownPixmap = Images::GetSmallDownIcon();
    m_pDownPixmap->label(pButton);

    // Finish this widget
    end();
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
SpinInput::~SpinInput()
{
    delete m_pUpPixmap;
    delete m_pDownPixmap;
}


//--------------------------------------------------------------//
// Down button callback                                         //
//--------------------------------------------------------------//
void
SpinInput::OnDownButton(Fl_Widget * pWidget, void *pUserData)
{
    int nValue;
    SpinInput *pThis = (SpinInput *) (pWidget->parent());

    // Decrement the value of this widget
    nValue = pThis->value() - 1;
    if (nValue >= pThis->m_nMin) {
	pThis->value(nValue);
    }
}


//--------------------------------------------------------------//
// Up button callback                                           //
//--------------------------------------------------------------//
void
SpinInput::OnUpButton(Fl_Widget * pWidget, void *pUserData)
{
    int nValue;
    SpinInput *pThis = (SpinInput *) (pWidget->parent());

    // Increment the value of this widget
    nValue = pThis->value() + 1;
    if (nValue <= pThis->m_nMax) {
	pThis->value(nValue);
    }
}


//--------------------------------------------------------------//
// Set the value of this widget                                 //
//--------------------------------------------------------------//
void
SpinInput::value(int nValue)
{
    char szData[16];

    if (nValue >= m_nMin && nValue <= m_nMax) {
	sprintf(szData, "%d", nValue);
	m_pInput->value(szData);
    }
}

--- NEW FILE: AddressBookCategoryDB.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Address Book Category database definition fields.            //
//--------------------------------------------------------------//
#include "AddressBookCategoryDB.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Pointer to the only one of these objects.                    //
//--------------------------------------------------------------//
AddressBookCategoryDB *
    AddressBookCategoryDB::m_pThis =
    NULL;


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
AddressBookCategoryDB::AddressBookCategoryDB()
:  CategoryDB("add_category", 10)
{
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
AddressBookCategoryDB::~AddressBookCategoryDB()
{
    m_pThis = NULL;
}


//--------------------------------------------------------------//
// Get a pointer to an open data base.                          //
//--------------------------------------------------------------//
AddressBookCategoryDB *
AddressBookCategoryDB::GetAddressBookCategoryDB()
{
    if (m_pThis == NULL) {
	m_pThis = new AddressBookCategoryDB;
    }
    return (m_pThis);
}

--- NEW FILE: NoteEditorDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Note Editor Dialog.                                          //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include <FL/Fl_Return_Button.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "NoteEditorDlg.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT 350
#define DLG_WIDTH  (3*DLG_BUTTON_WIDTH+4*DLG_BORDER)

//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
NoteEditorDlg::NoteEditorDlg(Note * pNote, Fl_Widget * pParent)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Edit Note"))
{
    m_pNoteEditor = new NoteEditor(DLG_BORDER,
				   DLG_BORDER,
				   w() - 2 * DLG_BORDER,
				   h() - DLG_BUTTON_HEIGHT - 3 * DLG_BORDER,
				   true, pNote);

    // Create the buttons
    m_pOKButton =
	new Fl_Return_Button(w() - 3 * (DLG_BUTTON_WIDTH + DLG_BORDER),
			     h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
			     DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton =
	new Fl_Button(w() - 2 * (DLG_BUTTON_WIDTH + DLG_BORDER),
		      h() - DLG_BUTTON_HEIGHT - DLG_BORDER, DLG_BUTTON_WIDTH,
		      DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				  h() - (DLG_BUTTON_HEIGHT + DLG_BORDER),
				  DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);

    // Finish the dialog
    end();

    m_pNote = NULL;

    // The DoModal method will show this dialog
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
NoteEditorDlg::~NoteEditorDlg()
{
}


//--------------------------------------------------------------//
// Run the modal dialog.                                        //
//--------------------------------------------------------------//
int
NoteEditorDlg::DoModal()
{
    int nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

    if (nReturn == 1) {
	// OK button was pressed, get the updated note
	m_pNote = m_pNoteEditor->GetNote();

	// Notify everyone of the changes
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
NoteEditorDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_NOTE_EDITOR_DLG);
}

--- NEW FILE: SpinInput.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// A class for what looks like a spin control.                  //
//--------------------------------------------------------------//
#ifndef SPININPUT_H_

#define SPININPUT_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <cstdlib>
#include <FL/Fl_Group.H>
#include <FL/Fl_Int_Input.H>
#include <FL/Fl_Pixmap.H>
class SpinInput:public Fl_Group
{
  public:SpinInput(int nX,	// Default constructor
	      int nY, int nWidth, int nHeight, const char *pszLabel,
	      int nMaxSize, int nMinimum, int nMaximum);
     ~SpinInput();		// Destructor
    inline int value()		// Get the value of this widget
    {
	return (atoi(m_pInput->value()));
    }
    void value(int nValue);	// Set the value of this widget
  private:Fl_Int_Input * m_pInput;
    // The input area
    Fl_Pixmap *m_pDownPixmap;	// The Down Button pixmap
    Fl_Pixmap *m_pUpPixmap;	// The Up Button pixmap
    int m_nMax;			// The maximum value
    int m_nMin;			// The minimum value
    static void OnDownButton(Fl_Widget * pWidget,	// Down button was clicked
			     void *pUserData);
    static void OnUpButton(Fl_Widget * pWidget,	// Up button was clicked
			   void *pUserData);
};


#endif /*  */

--- NEW FILE: Notes.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Center of the window for the Notes display                   //
//--------------------------------------------------------------//
#ifndef NOTES_H_

#define NOTES_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Group.H>
#include "Messages.h"
#include "NoteDetails.h"
#include "NoteEditor.h"
#include "NoteList.h"
class Notes:public Fl_Group
{
  public:Notes(Fl_Widget * pParent);
    // Default Constructor
    ~Notes();			// Destructor
    inline bool CanPaste() const	// Is there a row that can be pasted
    {
	return (m_vCopyString.size() > 0);
    }
    int Copy(int nRow);		// Copy a row to m_strCopyString
    int Cut(int nRow);		// Cut a row to m_strCopyString
    void Delete(int nRow);	// Delete a note
    inline void DisplayRow(int nRow)	// Display a particular row from the Notes List
    {
	m_pNoteDetails->DisplayRow(nRow, m_pCategory->value() - 1);
    }
    void EditNew();		// Insertion of a new Note row has been requested
    inline void Filter(int nCategory)	// Filter rows based on category
    {
	m_pNoteList->Filter(nCategory);
    }
    int Message(PixilDTMessage nMessage,	// Notification from the parent widget
		int nInfo);
    int Paste();		// Paste the most recently cut/copied row
    inline int SaveDetailChanges()	// Save any outstanding changes on the details window (return of 0 indicates the user said not to save)
    {
	return (m_pNoteDetails->SaveChanges(true));
    }
  private:bool m_bUndoCut;	// Can a cut be undone
    bool m_bUndoPaste;		// Can a paste be undone
    Fl_Box *m_pTitle;		// The page title
    Fl_Button *m_pNewButton;	// The new button
    Fl_Choice *m_pCategory;	// Category choice
    Fl_Menu_Item *m_pCategoryMenu;	// Category choice menu
    int m_nLastPaste;		// Last row pasted
    NoteDetails *m_pNoteDetails;	// The details for this note
    NoteList *m_pNoteList;	// The note list in the center of the window
    vector < string > m_vCopyString;	// Most recently copied or cut row
    static void CategorySelected(Fl_Widget * pWidget,	// Category filtering has been changed
				 void *pUserData);
    void FixDeletedCategory(int nCategory);	// Reset any entries with a deleted category back to Unfiled
    inline static void NewButton(Fl_Widget * pWidget,	// Callback for the New button
				 void *pUserData)
    {
	((Notes *) (pWidget->parent()))->EditNew();
    }
    void ResetCategoryChoice();	// Reset the category choice after a category deletion
    int Undo();			// Undo the most recent cut/paste
  public:void Refresh()
    {
	m_pNoteList->Refresh();
    }
};


#endif /*  */

--- NEW FILE: AddressBookDetails.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the Address Book Details.                          //
//--------------------------------------------------------------//
#ifndef ADDRESSBOOKDETAILS_H_

#define ADDRESSBOOKDETAILS_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Browser.H>
#include "Messages.h"
class AddressBookDetails:public Fl_Browser
{
  public:AddressBookDetails(int nX,
		       // Constructor
		       int nY, int nWidth, int nHeight);
     ~AddressBookDetails();	// Destructor
    void DisplayRow(int nRow);	// Display a row from the Address Book List
    int Message(PixilDTMessage nMessage,	// Process a message from the parent widget
		int nInfo);
  private:int m_nRow;		// Row currently being displayed
    void WrapText(const char *pszText);	// Break note text into multiple lines
};


#endif /*  */

--- NEW FILE: SchedulerTimeDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Dialog for the times for a Scheduler appointment.            //
//--------------------------------------------------------------//
#include "config.h"
#include <ctime>
#include <FL/fl_ask.H>
#include <FL/Fl_Return_Button.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "PixilDT.h"
#include "SchedulerTimeDlg.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT       (6*DLG_BORDER+3*DLG_BUTTON_HEIGHT)
#define DLG_INDENT       (DLG_BUTTON_WIDTH+2*DLG_BORDER)
#define DLG_WIDTH        (100+DLG_INDENT+3*DLG_BORDER+2*DLG_BUTTON_WIDTH)


//--------------------------------------------------------------//
// Constructor.                                                 //
//--------------------------------------------------------------//
SchedulerTimeDlg::SchedulerTimeDlg(time_t nStartTime,
				   time_t nEndTime, Fl_Widget * pParent)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Edit Appointment Times"))
{
    int nMinute;
    struct tm *pTm;

    // Create the dialog widgets
    m_pStartTime = new Fl_Output(DLG_INDENT,
				 DLG_BORDER,
				 DLG_WIDTH - 3 * DLG_BORDER -
				 2 * DLG_BUTTON_WIDTH - DLG_INDENT,
				 DLG_INPUT_HEIGHT, _("Start Time:"));
    m_pStartTime->color(FL_GRAY);
    m_pStartHour = new Fl_Choice(DLG_INDENT + m_pStartTime->w() + DLG_BORDER,
				 DLG_BORDER,
				 DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
    m_pStartHourMenu = GetHourMenu();
    m_pStartHour->menu(m_pStartHourMenu);
    m_pStartHour->callback(OnStartTime);
    m_pStartMinute =
	new Fl_Choice(DLG_INDENT + m_pStartTime->w() + 2 * DLG_BORDER +
		      DLG_BUTTON_WIDTH, DLG_BORDER, DLG_BUTTON_WIDTH,
		      DLG_BUTTON_HEIGHT);
    m_pStartMinuteMenu = GetMinuteMenu();
    m_pStartMinute->menu(m_pStartMinuteMenu);
    m_pStartMinute->callback(OnStartTime);
    m_pEndTime = new Fl_Output(DLG_INDENT,
			       2 * DLG_BORDER + DLG_BUTTON_HEIGHT,
			       DLG_WIDTH - 3 * DLG_BORDER -
			       2 * DLG_BUTTON_WIDTH - DLG_INDENT,
			       DLG_INPUT_HEIGHT, _("End Time:"));
    m_pEndTime->color(FL_GRAY);
    m_pEndHour = new Fl_Choice(DLG_INDENT + m_pStartTime->w() + DLG_BORDER,
			       2 * DLG_BORDER + DLG_BUTTON_HEIGHT,
			       DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
    m_pEndHourMenu = GetHourMenu();
    m_pEndHour->menu(m_pEndHourMenu);
    m_pEndHour->callback(OnEndTime);
    m_pEndMinute =
	new Fl_Choice(DLG_INDENT + m_pStartTime->w() + 2 * DLG_BORDER +
		      DLG_BUTTON_WIDTH, 2 * DLG_BORDER + DLG_BUTTON_HEIGHT,
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
    m_pEndMinuteMenu = GetMinuteMenu();
    m_pEndMinute->menu(m_pEndMinuteMenu);
    m_pEndMinute->callback(OnEndTime);

    // Create the buttons
    m_pOKButton =
	new Fl_Return_Button(w() - 3 * DLG_BUTTON_WIDTH - 3 * DLG_BORDER,
			     h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
			     DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton =
	new Fl_Button(w() - 2 * DLG_BUTTON_WIDTH - 2 * DLG_BORDER,
		      h() - DLG_BORDER - DLG_BUTTON_HEIGHT, DLG_BUTTON_WIDTH,
		      DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				  h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
				  DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);

    end();

    // Get the initial values for the data
    if (nStartTime < 24 * 60 * 60) {
	// No time set yet, use the current hour
	nStartTime = time(NULL);
	pTm = localtime(&nStartTime);
	if (pTm->tm_hour >= 23) {
	    --pTm->tm_hour;
	}
	m_pStartHour->value(pTm->tm_hour);
	m_pEndHour->value(pTm->tm_hour + 1);
	m_pStartMinute->value(0);
	m_pEndMinute->value(0);
    } else {
	// Set the end time (round to the nearest 5 minutes)
	pTm = localtime(&nEndTime);
	nMinute = (pTm->tm_min + 60 * pTm->tm_hour + 2) / 5;
	m_pEndHour->value(nMinute / 12);
	m_pEndMinute->value(nMinute % 12);

	// Set the start time (round to the nearest 5 minutes)
	pTm = localtime(&nStartTime);
	nMinute = (pTm->tm_min + 60 * pTm->tm_hour + 2) / 5;
	m_pStartHour->value(nMinute / 12);
	m_pStartMinute->value(nMinute % 12);
    }
    m_nYear = pTm->tm_year;
    m_nMonth = pTm->tm_mon;
    m_nDay = pTm->tm_mday;
    SetStartTime();
    SetEndTime();

    // The DoModal method will call show on this window
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
SchedulerTimeDlg::~SchedulerTimeDlg()
{
    FreeTranslatedMenu(m_pStartHourMenu);
    FreeTranslatedMenu(m_pStartMinuteMenu);
    FreeTranslatedMenu(m_pEndHourMenu);
    FreeTranslatedMenu(m_pEndMinuteMenu);
}


//--------------------------------------------------------------//
// Run the modal dialog                                         //
//--------------------------------------------------------------//
int
SchedulerTimeDlg::DoModal()
{
    bool bGood = false;
    int nReturn = 1;

    while (nReturn == 1 && bGood == false) {
	// Go run the dialog
	nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

	// Was the OK button pressed ?
	if (nReturn == 1) {
	    // Validate all fields
	    if (m_nEndTime <= m_nStartTime) {
		fl_alert(_("The End Time must be after the Start Time."));
	    } else {
		// Break out of the loop
		bGood = true;
	    }
	}
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Get the menu for an hour choice.                             //
//--------------------------------------------------------------//
Fl_Menu_Item *
SchedulerTimeDlg::GetHourMenu()
{
    char szLabel[24];
    Fl_Menu_Item *pMenuItem = new Fl_Menu_Item[25];
    int i;
    int nHour;
    string strAM;
    string strPM;

    PixilDT::GetAMPM(strAM, strPM);
    memset(pMenuItem, 0, 25 * sizeof(Fl_Menu_Item));
    for (i = 0; i < 24; ++i) {
	// Set up the menu text with strdup so that FreeTranslatedMenu will work properly
	if (strAM.length() != 0) {
	    // Twelve hour clock
	    nHour = (i % 12);
	    if (nHour == 0) {
		nHour = 12;
	    }
	    sprintf(szLabel, "%2d %s", nHour,
		    i >= 12 ? strPM.c_str() : strAM.c_str());
	} else {
	    // 24 hour clock
	    sprintf(szLabel, "%d", i);
	}
	pMenuItem[i].text = strdup(szLabel);
    }
    return (pMenuItem);
}


//--------------------------------------------------------------//
// Get the menu for a minute choice.                            //
//--------------------------------------------------------------//
Fl_Menu_Item *
SchedulerTimeDlg::GetMinuteMenu()
{
    char szLabel[16];
    Fl_Menu_Item *pMenuItem = new Fl_Menu_Item[13];
    int i;

    memset(pMenuItem, 0, 13 * sizeof(Fl_Menu_Item));
    for (i = 0; i < 12; ++i) {
	// Set up the menu text with strdup so that FreeTranslatedMenu will work properly
	sprintf(szLabel, "%02d", i * 5);
	pMenuItem[i].text = strdup(szLabel);
    }
    return (pMenuItem);
}


//--------------------------------------------------------------//
// Process a change to either of the end hour or end minute     //
// choices.                                                     //
//--------------------------------------------------------------//
void
SchedulerTimeDlg::OnEndTime(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerTimeDlg *pThis =
	reinterpret_cast < SchedulerTimeDlg * >(pWidget->parent());

    pThis->SetEndTime();
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
SchedulerTimeDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_SCHEDULER_TIME_DLG);
}


//--------------------------------------------------------------//
// Process a change to either or the start hour or start minute //
// choices.                                                     //
//--------------------------------------------------------------//
void
SchedulerTimeDlg::OnStartTime(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerTimeDlg *pThis =
	reinterpret_cast < SchedulerTimeDlg * >(pWidget->parent());

    pThis->SetStartTime();
}


//--------------------------------------------------------------//
// Set the end time from the choices.                           //
//--------------------------------------------------------------//
void
SchedulerTimeDlg::SetEndTime()
{
    struct tm tmStruct;

    // Create the time_t value for this time
    memset(&tmStruct, 0, sizeof(tmStruct));
    tmStruct.tm_isdst = -1;
    tmStruct.tm_min = m_pEndMinute->value() * 5;
    tmStruct.tm_hour = m_pEndHour->value();
    tmStruct.tm_mday = m_nDay;
    tmStruct.tm_mon = m_nMonth;
    tmStruct.tm_year = m_nYear;

    // Save the current end time
    m_nEndTime = mktime(&tmStruct);

    // Update the widget value
    m_pEndTime->value(::FormatTime(m_nEndTime).c_str());
}


//--------------------------------------------------------------//
// Set the start time from the choices.                         //
//--------------------------------------------------------------//
void
SchedulerTimeDlg::SetStartTime()
{
    struct tm tmStruct;

    // Create the time_t value for this time
    memset(&tmStruct, 0, sizeof(tmStruct));
    tmStruct.tm_isdst = -1;
    tmStruct.tm_min = m_pStartMinute->value() * 5;
    tmStruct.tm_hour = m_pStartHour->value();
    tmStruct.tm_mday = m_nDay;
    tmStruct.tm_mon = m_nMonth;
    tmStruct.tm_year = m_nYear;

    // Save the current end time
    m_nStartTime = mktime(&tmStruct);

    // Update the widget value
    m_pStartTime->value(::FormatTime(m_nStartTime).c_str());
}

--- NEW FILE: PixilDT.ini ---
[DataBase]
Path=/user/projects/pixil/pixil-1.2.2-pre10/pixilDT/src/data

[Search]
String=else

[ToDoList]
ShowCategory=Yes
ShowCompleted=Yes
ShowDueDate=Yes
ShowOnlyDue=No
ShowPriority=Yes
Sort=0

[Application]
ConfirmDelete=Yes
MainPage=3
SchedulerPage=0

[Scheduler]
DayBegins=8
WeekBegins=1


--- NEW FILE: AddressBookList.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the Address Book List.                             //
//--------------------------------------------------------------//
#include <FL/fl_draw.H>
#include "AddressBook.h"
#include "AddressBookCategoryDB.h"
#include "AddressBookList.h"
#include "AddressBookDB.h"
#include "FLTKUtil.h"
#include "Images.h"
#include "Messages.h"
#include "NoteEditorDlg.h"
#include "PixilDT.h"
#include "Printer.h"

#include "VCMemoryLeak.h"


#ifdef WIN32
// MS/Windows mis-named it
#define strcasecmp stricmp
#endif


//--------------------------------------------------------------//
// Icon column indications                                      //
//--------------------------------------------------------------//
const bool
    AddressBookList::m_bLargeIconColumns[ADDRESSBOOK_LARGE_COLUMNS] = {
	false,
	false,
	false,
	true,
true };

const bool
    AddressBookList::m_bSmallIconColumns[ADDRESSBOOK_SMALL_COLUMNS] = {
	false,
	true,
true };


//--------------------------------------------------------------//
// Category being filtered on                                   //
//--------------------------------------------------------------//
char
    AddressBookList::m_szCategory[16];


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
AddressBookList::AddressBookList(int nX,
				 int nY, int nWidth, int nHeight, bool bSmall)
    :
TableBase(nX, nY, nWidth, nHeight)
{
    m_bByLastName = true;
    m_bSmall = bSmall;
    m_nCategory = -1;		// Select all categories

    // Set no double click processing for a short display
    m_pfnDoubleClick = NULL;

    // Create the notes icon
    m_pNotesIcon = Images::GetNotesIcon();

    // Finish TableBase construction
    PostConstructor(AddressBookDB::GetAddressBookDB()->NumUndeletedRecs(),
		    bSmall ? ADDRESSBOOK_SMALL_COLUMNS :
		    ADDRESSBOOK_LARGE_COLUMNS,
		    bSmall ? m_bSmallIconColumns : m_bLargeIconColumns);

    // Display the details for the first line if it exists
    if (rows() > 0) {
	row(0);
	Refresh();
    }
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
AddressBookList::~AddressBookList()
{
    delete m_pNotesIcon;
}


//--------------------------------------------------------------//
// Calculate column widths after a resize.  The TableBase class //
// will already have set the m_nColWidth array to zeroes.       //
//--------------------------------------------------------------//
void
AddressBookList::CalculateColumnWidths(int nWidth)
{
    if (m_bSmall == true) {
	// Small display
	m_nColWidth[0] = nWidth - 12 - 12;	// All but two icons
	m_nColWidth[1] = 12;	// An icon
	m_nColWidth[2] = 12;	// An icon
    } else {
	// Large display
	m_nColWidth[0] = 55 * (nWidth - 12 - 12) / 100;	// 55% of all but two icons
	m_nColWidth[1] = 17 * (nWidth - 12 - 12) / 100;	// 17% of all but two icons
	m_nColWidth[2] = (nWidth - 12 - 12) - m_nColWidth[0] - m_nColWidth[1];	// The rest
	m_nColWidth[3] = 12;	// An icon
	m_nColWidth[4] = 12;	// An icon
    }
}


//--------------------------------------------------------------//
// Process a double click over a row.                           //
//--------------------------------------------------------------//
void
AddressBookList::DoubleClick(int nRow, int nCol)
{
    int nRow2 = AddressBookDB::GetAddressBookDB()->FindRealRow(nRow, m_vpRow);

    if (m_bSmall == false) {
	// Only process if not a small display
	((AddressBook *) parent())->Edit(nRow2);
    } else {
	// Perform custom processing for a small display
	if (m_pfnDoubleClick != NULL) {

	    (*m_pfnDoubleClick) (nRow2, nCol);
	}
    }
}


//--------------------------------------------------------------//
// Filter this list by category.                                //
//--------------------------------------------------------------//
void
AddressBookList::Filter(int nCategory)
{
    // Convert the category row to a category key
    if (nCategory != -1) {
	nCategory =
	    AddressBookCategoryDB::GetAddressBookCategoryDB()->
	    GetCategoryID(nCategory);
    }
    // Sort the rows in the database by category
    m_nCategory = nCategory;

    // Go refresh (and actually do the sort)
    Refresh();
}


//--------------------------------------------------------------//
// Get the icon for a column.  The icon is returned as an       //
// Fl_Pixmap pointer.                                           //
//--------------------------------------------------------------//
Fl_Pixmap *
AddressBookList::GetIconValue(int nRow, int nCol)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    Fl_Pixmap *pImage = NULL;

    if (m_bSmall == false) {
	// Large 5 column display
	switch (nCol) {
	case 3:		// Private icon - always blank for now
	    break;

	case 4:		// Notes icon - show if notes exist
	    nRow = pAddressBookDB->FindRealRow(nRow, m_vpRow);
	    if (pAddressBookDB->GetNoteFile(nRow).length() > 0) {
		// Get the notes icon                           pImage=m_pNotesIcon;

	    }
	    break;

	default:
#ifdef DEBUG
	    assert(false);	// Should not get here for some other column
#endif
	    ;
	}
    } else {
	// Smaller 3 column display
	switch (nCol) {
	case 1:		// Private icon - always blank for now
	    break;

	case 2:		// Notes icon - show if notes exist
	    nRow = pAddressBookDB->FindRealRow(nRow, m_vpRow);
	    if (pAddressBookDB->GetNoteFile(nRow).length() > 0) {
		// Get the notes icon
		pImage = m_pNotesIcon;
	    }
	    break;

	default:
#ifdef DEBUG
	    assert(false);	// Should not get here for some other column
#endif
	    ;
	}
    }

    return (pImage);
}


//--------------------------------------------------------------//
// Get the string value of a column.                            //
//--------------------------------------------------------------//
string
AddressBookList::GetStringValue(int nRow, int nCol)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    static const int nShowColumn[7] =
	{ AB_DEP1, AB_DEP2, AB_DEP3, AB_DEP4, AB_DEP5, AB_DEP6, AB_DEP7 };
    int nShow;
    string strReturn;

    // Translate the row number
    nRow = pAddressBookDB->FindRealRow(nRow, m_vpRow);

    // Get the data for the column
    switch (nCol) {
    case 0:			// First column
	if (m_bByLastName == true) {
	    // Set up the last name, first name string
	    strReturn = pAddressBookDB->GetLastName(nRow)
		+ ", " + pAddressBookDB->GetFirstName(nRow);
	} else {
	    // Set up by company name/last name
	    strReturn = pAddressBookDB->GetCompany(nRow)
		+ ", " + pAddressBookDB->GetLastName(nRow);
	}
	break;

    case 1:			// Second column, depends on the show flag
	// Fix for a bad show column
	nShow = pAddressBookDB->GetShowFlag(nRow);
	if (nShow < 0 || nShow > 6) {
	    nShow = 0;
	}
	// Get the column to be shown
	strReturn =
	    pAddressBookDB->GetInfoName(pAddressBookDB->
					GetInfoID(nRow, nShow));
	strReturn += ":";
	break;

    case 2:			// third column, depends on the show flag
	// Fix for a bad show column
	nShow = pAddressBookDB->GetShowFlag(nRow);
	if (nShow < 0 || nShow > 6) {
	    nShow = 0;
	}
	// Get the column to be shown
	strReturn += pAddressBookDB->GetStringValue(nRow, nShowColumn[nShow]);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Should not get here for some other column
#endif
	;
    }

    return (strReturn);
}


//--------------------------------------------------------------//
// Process a click over an icon column                          //
//--------------------------------------------------------------//
void
AddressBookList::IconClick(int nRow, int nCol)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();

    // Translate the row number
    nRow = pAddressBookDB->FindRealRow(nRow, m_vpRow);

    // Display the details for this line to the right
    SelectRow(nRow);

    // Process if a click over the Notes icon column and the line has notes
    if (((m_bSmall == true && nCol == 2) || (m_bSmall == false && nCol == 4))
	&& pAddressBookDB->GetNoteFile(nRow).length() > 0) {
	Note *pNote = pAddressBookDB->GetNote(nRow);
	NoteEditorDlg *pDlg =
	    new NoteEditorDlg(pNote, PixilDT::GetApp()->GetMainWindow());

	if (pDlg->DoModal() == 1) {
	    // OK button ended the dialog, save the note changes
	    pAddressBookDB->SetNote(nRow, pDlg->GetNote());

	    // Notify everyone of the changes
	    PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED,
						       0);
	}
	// Clean up
	delete pNote;
	delete pDlg;
    }
}


//--------------------------------------------------------------//
// Process a left mouse click over a non-icon column.           //
//--------------------------------------------------------------//
void
AddressBookList::LeftClick(int nRow, int nCol)
{
    // Display the details for this line to the right
    SelectRow(AddressBookDB::GetAddressBookDB()->FindRealRow(nRow, m_vpRow));
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
AddressBookList::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case ADDRESS_BOOK_CHANGED:
	Refresh();
	break;

    case ADDRESS_BOOK_GOTO:
	{
	    int nCount;
	    int nLocalRow;
	    int nRealRow;
	    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();

	    // Is this item visible ?
	    nLocalRow = pAddressBookDB->FindPhysicalRecord(nInfo, m_vpRow);
	    nCount = pAddressBookDB->NumRecsByCategory(m_nCategory);
	    if (nLocalRow >= nCount) {
		// Show all categories so this row can be seen
		m_nCategory = -1;

		// Refresh for this row
		nRealRow = pAddressBookDB->FindPhysicalRecord(nInfo);
		Refresh(pAddressBookDB->GetRecno(nRealRow));
	    } else {
		// The row is visible, just select it
		nRealRow = pAddressBookDB->FindPhysicalRecord(nInfo);
		SelectRow(nRealRow);
	    }
	}
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Print the Address Book as currently sorted.                  //
//--------------------------------------------------------------//
void
AddressBookList::Print()
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    bool bLastWasBox = false;
    char szLastChar[2] = "0";
    int nBorder = INCH / 2;	// 1/2 inch border
    int nChar;
    int nCopy;
    const int nFontSize = 10;
    int nInfo;
    int nRow;
    int nRow2;
    int nRows;
    Note *pNote;
    Printer printer;
    string strData;
    string strInfo;

    // Open the printer
    if (printer.Open(_("AddressBook")) == true) {
	// Set an hourglass cursor
	PixilDT::GetApp()->GetMainWindow()->SetCursor(FL_CURSOR_WAIT);

	// Print once for eqch requested copy
	for (nCopy = 0; nCopy < printer.GetCopies(); ++nCopy) {
	    // Reset the page number
	    printer.ResetPageNumber();

	    // Go to two column mode
	    printer.SetSerifFont(nFontSize);
	    printer.SetTwoColumnMode(425 * INCH / 100 - 2 * nBorder,
				     nBorder, _("Address Book"), NULL, 184);

	    // Print each visible entry
	    if (m_nCategory == -1) {
		// Show all rows
		nRows = pAddressBookDB->NumUndeletedRecs();
	    } else {
		// Get the selected category
		sprintf(m_szCategory, "%d", m_nCategory);

		// Filter by category
		nRows = pAddressBookDB->NumRecsByKey(AB_CAT, m_szCategory);
	    }

	    // Print each row
	    for (nRow = 0; nRow < nRows; ++nRow) {
		// Translate the row number
		nRow2 = pAddressBookDB->FindRealRow(nRow, m_vpRow);

		// Has the first character changed
		nChar = toupper(m_bByLastName == true
				? (pAddressBookDB->GetLastName(nRow2))[0]
				: (pAddressBookDB->GetCompany(nRow2))[0]);
		if (nRow == 0 || nChar != szLastChar[0]) {
		    // Yes, output a box for the character
		    szLastChar[0] = nChar;
		    printer.ColumnSpaceLine();
		    printer.ColumnSpaceLine();
		    printer.ColumnSpaceLine();
		    printer.ColumnBox(szLastChar, 15, 5 * INCH / 16, 184);
		    bLastWasBox = true;
		}
		// Output this person's data
		if (nRow != 0 && bLastWasBox == false) {
		    printer.ColumnNewLine();
		}
		bLastWasBox = false;

		// Output person or company name
		if (m_bByLastName == true) {
		    // Get the last name
		    strData = pAddressBookDB->GetFirstName(nRow2);
		    strData += ' ';
		    strData += pAddressBookDB->GetLastName(nRow2);
		} else {
		    // Get the company
		    strData = pAddressBookDB->GetCompany(nRow2);
		}

		// Output the identifier
		printer.SetBoldSerifFont(nFontSize);
		printer.ColumnShowNoAdvance(strData.c_str(), 0);
		printer.SetSerifFont(nFontSize);

		// Output the category
		printer.ColumnShowNoAdvanceRight(pAddressBookDB->
						 GetCategoryName(nRow).
						 c_str(), 0);
		printer.ColumnNewLine();

		// Output the title
		printer.ColumnShow(pAddressBookDB->GetTitle(nRow).c_str(),
				   INCH / 4, 0);

		// Output the company or person name
		if (m_bByLastName == true) {
		    // Get the company
		    strData = pAddressBookDB->GetCompany(nRow2);
		} else {
		    // Get the last name
		    strData = pAddressBookDB->GetFirstName(nRow2);
		    strData += ' ';
		    strData += pAddressBookDB->GetLastName(nRow2);
		}
		printer.ColumnShow(strData.c_str(), INCH / 4, 0);

		// Output each of the info fields
		for (nInfo = 0; nInfo < 7; ++nInfo) {
		    strInfo = pAddressBookDB->GetInfo(nRow2, nInfo);
		    if (strInfo.length() > 0) {
			strData = pAddressBookDB->GetInfoName(nRow2, nInfo);
			strData += ':';
			printer.SetBoldSerifFont(nFontSize);
			printer.ColumnShowNoAdvance(strData.c_str(),
						    INCH / 4);
			printer.SetSerifFont(nFontSize);
			printer.ColumnShow(strInfo.c_str(), (5 * INCH) / 4,
					   0);
		    }
		}

		// Output the address
		printer.ColumnShow(pAddressBookDB->GetAddress(nRow2).c_str(),
				   INCH / 4, 0);
		strData = pAddressBookDB->GetCity(nRow2);
		strData += ", ";
		strData += pAddressBookDB->GetRegion(nRow2);
		strData += ' ';
		strData += pAddressBookDB->GetPostalCode(nRow2);
		printer.ColumnShow(strData.c_str(), INCH / 4, 0);
		strData = pAddressBookDB->GetCountry(nRow2);
		if (strData.length() > 0) {
		    printer.ColumnShow(strData.c_str(), INCH / 4, 0);
		}
		// Output the custom fields
		for (nInfo = 0; nInfo < 4; ++nInfo) {
		    strInfo = pAddressBookDB->GetCustomField(nRow2, nInfo);
		    if (strInfo.length() > 0) {
			strData = pAddressBookDB->GetCustomFieldName(nInfo);
			strData += ':';
			printer.ColumnShowNoAdvance(strData.c_str(),
						    INCH / 4);
			printer.ColumnShow(strInfo.c_str(), (5 * INCH) / 4,
					   0);
		    }
		}

		// Output the note
		pNote = pAddressBookDB->GetNote(nRow2);
		if (pNote->GetText().length() > 0) {
		    printer.ColumnShowNoAdvance(_("Notes:"), INCH / 4);
		    printer.ColumnShow(pNote->GetText().c_str(),
				       (5 * INCH) / 4, 0);
		}
		delete pNote;
	    }

	    // End the page
	    printer.EndTwoColumnMode();
	}

	// All done, close the printer
	printer.Close();

	// Reset the cursor
	PixilDT::GetApp()->GetMainWindow()->ResetCursor();
    }
}


//--------------------------------------------------------------//
// Refresh this list.                                           //
//--------------------------------------------------------------//

void
AddressBookList::Refresh(int nID)
{

    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    m_vpRow = pAddressBookDB->GetRows();

    int nLocalRow = row();
    int nRealRow;
    int nRows = pAddressBookDB->NumUndeletedRecs();

    // Get the currently selected row
    if (nID < 0) {
	if (nRows > 0 && nLocalRow >= 0 && m_vpRow.size() > 0) {
	    // Get the row's ID number
	    nID =
		pAddressBookDB->GetRecno(pAddressBookDB->
					 FindRealRow(nLocalRow, m_vpRow));
	} else {
	    // No row currently selected
	    nID = -1;
	}
    }
    // Get a copy of the rows
    m_vpRow = pAddressBookDB->GetRows();

    // Re-sort the data base
    if (m_nCategory == -1) {
	// Sort for all categories
	pAddressBookDB->Sort(m_bByLastName ==
			     true ? SortCompare1 : SortCompare2, m_vpRow);
	nRows = pAddressBookDB->NumUndeletedRecs();
    } else {
	// Get the selected category
	sprintf(m_szCategory, "%d", m_nCategory);

	// Filter by category
	pAddressBookDB->Sort(m_bByLastName ==
			     true ? SortCategory1 : SortCategory2, m_vpRow);
	nRows = pAddressBookDB->NumRecsByKey(AB_CAT, m_szCategory);
    }
    row(-1);			// Workaround for inadvertant top_row update
    rows(nRows);

    // Find the row to be selected
    if (nID >= 0) {
	// Get the row number for the selected ID
	nRealRow = pAddressBookDB->FindRecno(nID);
	if (nRealRow >= 0) {
	    nLocalRow = pAddressBookDB->GetLocalRow(nRealRow, m_vpRow);
	} else {
	    nLocalRow = -1;
	}
    } else {
	nLocalRow = -1;
    }
    if (nLocalRow >= 0) {
	// See if visible based on selected category
	if (m_nCategory != -1) {
	    if (nLocalRow >=
		pAddressBookDB->NumRecsByKey(AB_CAT, m_szCategory)) {
		// Not visible, reselect row 0
		nLocalRow = 0;
	    }
	}
    } else {
	nLocalRow = 0;
    }
    row(nLocalRow);

    // Cause the list to be redrawn
    redraw();
    SelectRow(nRows >
	      0 ? pAddressBookDB->FindRealRow(nLocalRow, m_vpRow) : -1);
}


//--------------------------------------------------------------//
// Process a right mouse click anywhere                         //
//--------------------------------------------------------------//
void
AddressBookList::RightClick(int nRow, int nCol)
{
    static const Fl_Menu_Item menuPopup1[] = {
	{N_("Delete Address")},
	{N_("Copy Address")},
	{N_("Cut Address")},
	{N_("Edit Address"), 0, 0, 0, FL_MENU_DIVIDER},
	{N_("New Address")},
	{N_("Paste Address")},
	{NULL},
    };
    static const Fl_Menu_Item menuPopup2[] = {
	{N_("Delete Address")},
	{N_("Copy Address")},
	{N_("Cut Address")},
	{N_("Edit Address"), 0, 0, 0, FL_MENU_DIVIDER},
	{N_("New Address")},
	{NULL},
    };
    const Fl_Menu_Item *pmenuPopup;
    int nRealRow;
    int nSelection;

    // Translate the row number
    if (nRow >= 0) {
	nRealRow =
	    AddressBookDB::GetAddressBookDB()->FindRealRow(nRow, m_vpRow);
    } else {
	nRealRow = -1;
    }

    // Display the details for this line to the right
    SelectRow(nRealRow);

    if (m_bSmall == false) {
	// Only process if not a small display
	// Display the popup menu
	pmenuPopup = ((AddressBook *) parent())->CanPaste()
	    ? menuPopup1 : menuPopup2;
	nSelection = DoPopupMenu((nRow >= 0 ? pmenuPopup : &pmenuPopup[4]),
				 Fl::event_x(), Fl::event_y());

	if (nSelection >= 0) {
	    // Fix the selection for the shorter menu
	    nSelection += (nRow < 0 ? 4 : 0);

	    // Process the selection
	    switch (nSelection) {
	    case 0:		// Delete this row
		((AddressBook *) parent())->Delete(nRealRow);
		break;

	    case 1:		// Copy this row
		((AddressBook *) parent())->Copy(nRealRow);
		break;

	    case 2:		// Cut this row
		((AddressBook *) parent())->Cut(nRealRow);
		break;

	    case 3:		// Edit this row
		((AddressBook *) parent())->Edit(nRealRow);
		break;

	    case 4:		// Insert a new row
		((AddressBook *) parent())->EditNew();
		break;

	    case 5:		// Paste a row
		((AddressBook *) parent())->Paste();
	    }
	}
    }
}


//--------------------------------------------------------------//
// Search for a row beginning with these characters.            //
//--------------------------------------------------------------//
bool
AddressBookList::Search(const char *pszValue)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    bool bReturn;
    int nCol = (m_bByLastName == true ? AB_LASTNAME : AB_COMPANY);
    int nRow = pAddressBookDB->FindFirst(nCol, pszValue);

#ifdef WIN32
    // Beep if an error under Windows
    if (nRow == -1) {
	MessageBeep(MB_ICONQUESTION);
    }
#endif

    // Don't change the row if an error occurred
    if (nRow == -1) {
	bReturn = false;
    } else {
	// No error, change the row
	bReturn = true;

	// Select this row
	nRow = pAddressBookDB->GetLocalRow(nRow, m_vpRow);
	SelectRow(nRow);
    }

    // Set to the selected row
    return (bReturn);
}


//--------------------------------------------------------------//
// Select a row and inform the parent of the selection.         //
//--------------------------------------------------------------//
void
AddressBookList::SelectRow(int nRealRow)
{
    int nLocalRow;

    // Translate the row number
    if (nRealRow >= 0) {
	nLocalRow =
	    AddressBookDB::GetAddressBookDB()->GetLocalRow(nRealRow, m_vpRow);
    } else {
	nLocalRow = -1;
    }

    // Select this row
    row(nLocalRow);

    // Only notify the parent if not a small display
    if (m_bSmall == false) {
	// Tell the parent
	((AddressBook *) parent())->DisplayRow(nRealRow);
    }
}


//--------------------------------------------------------------//
// Compare by last name, first name and filter by category for  //
// sorting.                                                     //
//--------------------------------------------------------------//
bool
AddressBookList::SortCategory1(NxDbRow * pRow1, NxDbRow * pRow2)
{
    bool bReturn;

    // Is the first row the correct category
    if (pRow1->GetStringValue(AB_CAT) == m_szCategory) {
	// Is the second row the correct category
	if (pRow2->GetStringValue(AB_CAT) == m_szCategory) {
	    // Both good, sort like normal
	    bReturn = SortCompare1(pRow1, pRow2);
	} else {
	    // First is good, second is not, say first is lower
	    bReturn = true;
	}
    } else {
	// Is the second row the correct category
	if (pRow2->GetStringValue(AB_CAT) == m_szCategory) {
	    // First is not good, second is good, say first is not lower
	    bReturn = false;
	} else {
	    // Both not good, sort like normal
	    bReturn = SortCompare1(pRow1, pRow2);
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Compare by company name, last name and filter by category    //
// for sorting.                                                 //
//--------------------------------------------------------------//
bool
AddressBookList::SortCategory2(NxDbRow * pRow1, NxDbRow * pRow2)
{
    bool bReturn;

    // Is the first row the correct category
    if (pRow1->GetStringValue(AB_CAT) == m_szCategory) {
	// Is the second row the correct category
	if (pRow2->GetStringValue(AB_CAT) == m_szCategory) {
	    // Both good, sort like normal
	    bReturn = SortCompare2(pRow1, pRow2);
	} else {
	    // First is good, second is not, say first is lower
	    bReturn = true;
	}
    } else {
	// Is the second row the correct category
	if (pRow2->GetStringValue(AB_CAT) == m_szCategory) {
	    // First is not good, second is good, say first is not lower
	    bReturn = false;
	} else {
	    // Both not good, sort like normal
	    bReturn = SortCompare1(pRow1, pRow2);
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Compare by last name, first name for sorting.                //
//--------------------------------------------------------------//
bool
AddressBookList::SortCompare1(NxDbRow * pRow1, NxDbRow * pRow2)
{
    bool bReturn;
    string strString1 = pRow1->GetStringValue(AB_LASTNAME);
    string strString2 = pRow2->GetStringValue(AB_LASTNAME);

    if (strcasecmp(strString1.c_str(), strString2.c_str()) < 0) {
	bReturn = true;
    } else if (strcasecmp(strString1.c_str(), strString2.c_str()) > 0) {
	bReturn = false;
    } else			// equal
    {
	bReturn = (strcasecmp(pRow1->GetStringValue(AB_FIRSTNAME).c_str(),
			      pRow2->GetStringValue(AB_FIRSTNAME).c_str()) <
		   0);
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Compare by company name, last name for sorting.              //
//--------------------------------------------------------------//
bool
AddressBookList::SortCompare2(NxDbRow * pRow1, NxDbRow * pRow2)
{
    bool bReturn;
    string strString1 = pRow1->GetStringValue(AB_COMPANY);
    string strString2 = pRow2->GetStringValue(AB_COMPANY);

    if (strcasecmp(strString1.c_str(), strString2.c_str()) < 0) {
	bReturn = true;
    } else if (strcasecmp(strString1.c_str(), strString2.c_str()) > 0) {
	bReturn = false;
    } else			// equal
    {
	bReturn = (strcasecmp(pRow1->GetStringValue(AB_LASTNAME).c_str(),
			      pRow2->GetStringValue(AB_LASTNAME).c_str()) <
		   0);
    }
    return (bReturn);
}

--- NEW FILE: SchedulerYearly.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler Yearly tab page                                    //
//--------------------------------------------------------------//
#ifndef SCHEDULERYEARLY_H_

#define SCHEDULERYEARLY_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <ctime>
#include <string>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Pixmap.H>
#include "Messages.h"
using namespace std;
class SchedulerYearly:public Fl_Group
{
  public:SchedulerYearly(int nX,
		    // Constructor
		    int nY, int nWidth, int nHeight);
     ~SchedulerYearly();	// Destructor
    int Message(PixilDTMessage nMessage,	// Message from the parent widget
		int nInfo);
    void Print();		// Print this page
  private:  bool m_bEvent[366];
    // Event flags for each day of the year
    Fl_Box *m_pDate;		// Date banner at the top of the page
    Fl_Button *m_pGoToButton;	// Goto button
    Fl_Button *m_pLeftButton;	// Left arrow button
    Fl_Button *m_pRightButton;	// Right arrow button
    Fl_Button *m_pTodayButton;	// Today button
    Fl_Group *m_pMonth[12];	// A group for each month
    Fl_Pixmap *m_pLeftPixmap;	// Left arrow pixmap
    Fl_Pixmap *m_pRightPixmap;	// Right arrow pixmap
    string m_strDateLabel;	// Label for the banner at the top of the page
    string m_strMonthLabel[12];	// The month names
    time_t m_nDate;		// Date currently being displayed
    void CreateMonth(int nIndex);	// Create a month's boxes
    void DisplayDay(time_t nDate);	// Go display a particular day's year
    static void OnGotoButton(Fl_Widget * pWidget,	// Process a click on the goto buttton
			     void *pUserData);
    static void OnLeftButton(Fl_Widget * pWidget,	// Process a click on the left buttton
			     void *pUserData);
    static void OnRightButton(Fl_Widget * pWidget,	// Process a click on the right buttton
			      void *pUserData);
    static void OnTodayButton(Fl_Widget * pWidget,	// Process a click on the today buttton
			      void *pUserData);
    void UpdateMonth(int nIndex);	// Update the monthly group after a change in dates or events
    static bool ValidateYear(const char *pszString,	// Validate an entered year for "goto"
			     Fl_Widget * pWidget, void *pUserData);
  public:void Refresh()
    {
	DisplayDay(m_nDate);
    }
};


#endif /*  */

--- NEW FILE: SchedulerChangeTypeDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// A dialog to ask about how to apply changes to a scheduled    //
// event.                                                       //
//--------------------------------------------------------------//
#ifndef SCHEDULERCHANGETYPEDLG_H_

#define SCHEDULERCHANGETYPEDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Button.H>
#include <FL/Fl_Window.H>

#define SCHEDULER_CHANGE_TYPE_ALL            1
#define SCHEDULER_CHANGE_TYPE_CURRENT_FUTURE 2
#define SCHEDULER_CHANGE_TYPE_CURRENT_ONLY   3
#define SCHEDULER_CHANGE_TYPE_NONE          -1
class SchedulerChangeTypeDlg:public Fl_Window
{
  public:SchedulerChangeTypeDlg(Fl_Widget * pParent,
			   // Constructor
			   bool bDelete);
    ~SchedulerChangeTypeDlg();	// Destructor
    int DoModal();		// Run the modal dialog
    inline int GetChangeType() const	// Get the requested change type
    {
	return (m_nChangeType);
    }
  private:  Fl_Button * m_pAllButton;
    // The "All events" button
    Fl_Button *m_pCancelButton;	// The Cancel button
    Fl_Button *m_pCurrentButton;	// The "Current event only" button
    Fl_Button *m_pFutureButton;	// The "Current and future events" button
    int m_nChangeType;		// The requested change type
    static void OnAllButton(Fl_Widget * pWidget,	// Callback for the All button
			    void *pUserData);
    static void OnCurrentButton(Fl_Widget * pWidget,	// Callback for the Current button
				void *pUserData);
    static void OnFutureButton(Fl_Widget * pWidget,	// Callback for the Current + Future button
			       void *pUserData);
};


#endif /*  */

--- NEW FILE: TableBase.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Base class for table based widgets, in turn based on         //
// FLVW_Table.                                                  //
//--------------------------------------------------------------//
#include <cstring>
#include <FL/Fl.H>
#include <FL/forms.H>
#include <FL/fl_draw.H>
#include "TableBase.h"

#include "FLTKUtil.h"
#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
TableBase::TableBase(int nX, int nY, int nWidth, int nHeight)
    :
Flv_Table(nX, nY, nWidth, nHeight)
{
    // Used in col_width in derived classes
    m_nLastWidth = -1;

    // Default initialization
    m_nColumns = 0;
    m_pbIconColumns = NULL;

    // Set up the scrollbars
    has_scrollbar(FLVS_AUTOMATIC + FLVS_VERTICAL);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
TableBase::~TableBase()
{
    // Delete the saved icon column indications
    delete[]m_pbIconColumns;
}


//--------------------------------------------------------------//
// Calculate column widths after a resize.                      //
//--------------------------------------------------------------//
int
TableBase::col_width(int nCol)
{
    int nScrollbarWidth = (scrollbar.visible()? scrollbar.w() : 0);
    int nWidth = w() - nScrollbarWidth - 1;	//-2*Fl::box_dw(FL_DOWN_BOX);

    // Either always calculate or be sure to check that width has not changed
    if (nWidth != m_nLastWidth) {
	// Width change, recalculate
	memset(m_nColWidth, 0, sizeof(m_nColWidth));

	// Call on the derived widget to calculate column widths into m_nColWidth
	CalculateColumnWidths(nWidth);

	// Set the last width for the next call
	m_nLastWidth = nWidth;
    }
    return (m_nColWidth[nCol]);
}


//--------------------------------------------------------------//
// Draw a cell.                                                 //
//--------------------------------------------------------------//
void
TableBase::draw_cell(int nOffset,
		     int &nX,
		     int &nY, int &nWidth, int &nHeight, int nRow, int nCol)
{
    Flv_Style s;

    Flv_Table::draw_cell(nOffset, nX, nY, nWidth, nHeight, nRow, nCol);
    get_style(s, nRow, nCol);
    if (m_pbIconColumns[nCol] == false) {
	// Non-icon column, get the text
	fl_draw(GetStringValue(nRow, nCol).c_str(),
		nX - nOffset, nY, nWidth, nHeight, s.align());
    } else {
	Fl_Pixmap *pImage;
	int nImageHeight;
	int nImageWidth;

	// Icon column, get the icon
	pImage = GetIconValue(nRow, nCol);
	if (pImage != NULL) {
	    fl_measure_pixmap(pImage->data, nImageWidth, nImageHeight);
	    pImage->draw(nX + ((nWidth - nImageWidth) >> 1),
			 nY + ((nHeight - nImageHeight) >> 1));
	}
    }
}


//--------------------------------------------------------------//
// Event handler                                                //
//--------------------------------------------------------------//
int
TableBase::handle(int nEvent)
{

    int nCol = get_col(Fl::event_x(), Fl::event_y());
    int nReturn = Flv_Table::handle(nEvent);
    int nRow = get_row(Fl::event_x(), Fl::event_y());


    switch (nEvent) {
    case FL_PUSH:		// Mouse button pushed
	if (Fl::event_button() == FL_LEFT_MOUSE) {
	    // Ask for release if not in a grey area
	    nReturn = (nRow != -4 ? 1 : 0);
	} else if (Fl::event_button() == FL_RIGHT_MOUSE) {
	    // Ask for release
	    nReturn = 1;
	}
	break;

    case FL_RELEASE:		// Mouse button released
	if (Fl::event_button() == FL_LEFT_MOUSE) {
	    if (nRow >= 0) {
		if (Fl::event_clicks() > 0) {
		    // Double click on a row, go process it
		    DoubleClick(nRow, nCol);
		    nReturn = 1;
		} else {
		    // Single click on a row, was it on an icon
		    if (m_pbIconColumns[nCol] == true) {
			// Go process a click on an icon
			IconClick(nRow, nCol);
			nReturn = 1;
		    } else {
			// Go process a click on a non-icon column
			LeftClick(nRow, nCol);
			nReturn = 1;
		    }
		}
	    }
	} else if (Fl::event_button() == FL_RIGHT_MOUSE) {
	    // If on a row or on a gray area then do a popup menu
	    if (nRow >= 0 || nRow == -4) {
		// Do a popup menu
		RightClick(nRow, nCol);
		nReturn = 1;
	    }
	}
	break;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Post construction code that will cause the widget to be      //
// re-drawn which will in turn invoke pure virtual functions.   //
// This code had to be removed from the TableBase constructor   //
// and must be called from the derived classes constructor.     //
//--------------------------------------------------------------//
void
TableBase::PostConstructor(int nRows,
			   int nColumns, const bool * pbIconColumns)
{

    // Save the column information
    m_nLastWidth = -1;		// Reset to force column width recalculation
    m_nColumns = nColumns;
    delete m_pbIconColumns;
    m_pbIconColumns = new bool[nColumns];
    memcpy(m_pbIconColumns, pbIconColumns, nColumns);

    // Set up the table
    color(FL_WHITE);
    selection_color(FL_SELECTION_COLOR);
    cols(nColumns);
    rows(nRows);

    // Set full row selection
    feature_add(FLVF_ROW_SELECT);
}

--- NEW FILE: SchedulerRepeatDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Dialog for setting Scheduler repeat options.                 //
//--------------------------------------------------------------//
#ifndef SCHEDULERREPEATDLG_H_

#define SCHEDULERREPEATDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Window.H>
#include "SchedulerDB.h"
#include "SpinInput.h"
class SchedulerRepeatDlg:public Fl_Window
{
  public:SchedulerRepeatDlg(const SchedulerRepeatData *
		       pSchedulerRepeatData,
		       // Constructor
		       Fl_Widget * pParent);
     ~SchedulerRepeatDlg();	// Destructor
    int DoModal();		// Run the modal dialog
    const SchedulerRepeatData & GetSchedulerRepeatData() const	// Get the repetition settings
    {
	return (*m_pSchedulerRepeatData);
    }
  private:  Fl_Button * m_pCancelButton;
    // The Cancel button
    Fl_Button *m_pHelpButton;	// The Help button
    Fl_Button *m_pOKButton;	// The OK button
    Fl_Button *m_pWeekDayButton[7];	// The days of the week for the weekly page
    Fl_Check_Button *m_pRadioButton[5];	// The five radio buttons for the various repeat choices
    Fl_Choice *m_pMonthBy;	// Choice for how month repetitions are handled
    Fl_Group *m_pPage[5];	// Each of the pages
    Fl_Group *m_pWeekDays;	// Group containing week day buttons for the weekly page
    Fl_Input *m_pDayEnd;	// The end for daily repeats
    Fl_Input *m_pMonthEnd;	// The end for monthly repeats
    Fl_Input *m_pWeekEnd;	// The end for weekly repeats
    Fl_Input *m_pYearEnd;	// The end for yearly repeats
    Fl_Menu_Item *m_pMonthMenu;	// The menu for the choice on the monthly page
    Fl_Pixmap *m_pDayCalendarPixmap;	// The pixmap for the daily end date calendar button
    Fl_Pixmap *m_pMonthCalendarPixmap;	// The pixmap for the monthly end date calendar button
    Fl_Pixmap *m_pWeekCalendarPixmap;	// The pixmap for the weekly end date calendar button
    Fl_Pixmap *m_pYearCalendarPixmap;	// The pixmap for the yearly end date calendar button
    SchedulerRepeatData *m_pSchedulerRepeatData;	// The current repeat settings
    SpinInput *m_pDayEvery;	// The number of days between repeats
    SpinInput *m_pMonthEvery;	// The number of months between repeats
    SpinInput *m_pWeekEvery;	// The number of weeks between repeats
    SpinInput *m_pYearEvery;	// The number of years between repeats
    string m_strRadioLabel[5];	// Labels for the radio buttons
    string m_strWeekdayLabel[7];	// Labels for the days-of-week for theweekly page
    void CreateEndDate(int nIndex);	// Create end date widgets
    void CreatePage1(int nX,	// Create the "page" for the first (None) radio button
		     int nY, int nWidth, int nHeight);
    void CreatePage2(int nX,	// Create the "page" for the seocnd (Daily) radio button
		     int nY, int nWidth, int nHeight);
    void CreatePage3(int nX,	// Create the "page" for the third (Weekly) radio button
		     int nY, int nWidth, int nHeight);
    void CreatePage4(int nX,	// Create the "page" for the fourth (Monthly) radio button
		     int nY, int nWidth, int nHeight);
    void CreatePage5(int nX,	// Create the "page" for the fifth (Yearly) radio button
		     int nY, int nWidth, int nHeight);
    void CreateSpinButton(int nIndex);	// Create a spin button set of widgets
    static void OnDateButton(Fl_Widget * pWidget,	// Process click on one of the Date buttons
			     void *pUserData);
    static void OnHelpButton(Fl_Widget * pWidget,	// Process click on the Help button
			     void *pUserData);
    static void OnRadioButton(Fl_Widget * pWidget,	// Process click on one of the radio buttons
			      void *pUserData);
    static void OnWeekDay(Fl_Widget * pWidget,	// Process click on one of the day-of-week buttons
			  void *pUserData);
};


#endif /*  */

--- NEW FILE: ImageBox.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for a box with an image and which tracks mouse         //
// movements and allows left mouse clicks on the image.         //
//--------------------------------------------------------------//
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include "FLTKUtil.h"
#include "ImageBox.h"
#include "LeftGroup.h"

#include <cstdio>

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
ImageBox::ImageBox(int nX,
		   int nY,
		   int nWidth,
		   int nHeight,
		   Fl_Pixmap * pPixmap,
		   PixilDTMessage nMessage, const char *pszPrompt)
    :
Fl_Group(nX, nY, nWidth, nHeight, "")
{
    int i;
    unsigned int nColor;
    unsigned int nComponent;
    unsigned int nNewColor;

    // Save the prompt string
    m_strPrompt = pszPrompt;

    // Set the color for this group
    m_nNormalColor = parent()->color();
    color(m_nNormalColor);
    box(FL_UP_BOX);

    // Generate the down color
    nColor = Fl::get_color(m_nNormalColor);
    for (nNewColor = 0, i = 0; i < 24; i += 8) {
	nComponent = ((((nColor >> (24 - i)) & 0xff) + 0x100) >> 1);
	nNewColor += (nComponent << i);
    }
    m_nDownColor = GetFLTKColor(nNewColor);

    // No child widgets
    end();

    // Create the image
    m_pPixmap = pPixmap;
    m_pPixmap->label(this);
    align(FL_ALIGN_CENTER | FL_ALIGN_CLIP);

    // Save the notification message number
    m_nMessage = nMessage;

    // Display this widget
    show();

    // Initialize mouse tracking
    m_bMouseDown = m_bMouseIn = false;
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
ImageBox::~ImageBox()
{
    delete m_pPixmap;
}


//--------------------------------------------------------------//
// Draw this widget.                                            //
//--------------------------------------------------------------//
void
ImageBox::draw()
{
    int nHeight;
    int nWidth;

    // Draw the box
    draw_box();

    // Draw the image
    fl_measure_pixmap(m_pPixmap->data, nWidth, nHeight);
    m_pPixmap->draw(x() + ((w() - nWidth) >> 1), y() + 6);

    // Draw the text
    fl_font(labelfont(), (3 * labelsize()) >> 2);
    fl_color(FL_BLACK);
    fl_draw(m_strPrompt.c_str(), x(), y() + h() - 14, w(), 14, FL_ALIGN_CLIP);
}


//--------------------------------------------------------------//
// Event handler                                                //
//--------------------------------------------------------------//
int
ImageBox::handle(int nEvent)
{
    int nReturn = Fl_Group::handle(nEvent);

    switch (nEvent) {
    case FL_ENTER:
	nReturn = 1;
	m_bMouseIn = true;
	if (m_bMouseDown == true) {
	    PopDown();
	}
	break;

    case FL_LEAVE:
	nReturn = 1;
	m_bMouseIn = false;
	if (m_bMouseDown == true) {
	    PopUp();
	    m_bMouseDown = false;
	}
	break;

    case FL_PUSH:
	PopDown();
	nReturn = 1;
	m_bMouseDown = true;
	dynamic_cast < LeftGroup * >(parent())->Notify(m_nMessage, 0);
	break;

    case FL_RELEASE:
	nReturn = 1;
	m_bMouseDown = false;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Process notifications from the parent widget.  This allows   //
// this widget to act like a radio button, if the passed        //
// message is not the message number for this widget then it    //
// will be popped up.                                           //
//--------------------------------------------------------------//
int
ImageBox::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    // If the message number does not match this widget's message then pop the button up
    if (nMessage != m_nMessage) {
	PopUp();
    } else {
	PopDown();
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Pop this widget down.                                        //
//--------------------------------------------------------------//
void
ImageBox::PopDown()
{
    box(FL_DOWN_BOX);
    color(m_nDownColor);
    redraw();
}


//--------------------------------------------------------------//
// Pop this widget up.                                          //
//--------------------------------------------------------------//
void
ImageBox::PopUp()
{
    box(FL_UP_BOX);
    color(m_nNormalColor);
    redraw();
}

--- NEW FILE: ListByDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// List By Dialog.                                              //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "ListByDlg.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT 200
#define DLG_WIDTH  400


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
ListByDlg::ListByDlg(bool bSelection, Fl_Widget * pParent)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Change Address Book Order"))
{
    m_pRadioButton[0] = new Fl_Check_Button(DLG_BORDER,
					    DLG_BORDER,
					    DLG_RADIO_SIZE,
					    DLG_RADIO_SIZE,
					    _
					    ("Sort by &Last Name then First Name"));
    m_pRadioButton[0]->type(FL_RADIO_BUTTON);
    m_pRadioButton[0]->down_box(FL_ROUND_DOWN_BOX);
    m_pRadioButton[0]->align(FL_ALIGN_RIGHT);
    m_pRadioButton[1] = new Fl_Check_Button(DLG_BORDER,
					    DLG_BORDER +
					    2 * DLG_BUTTON_HEIGHT,
					    DLG_RADIO_SIZE, DLG_RADIO_SIZE,
					    _
					    ("Sort by &Company Name then Last Name"));
    m_pRadioButton[1]->type(FL_RADIO_BUTTON);
    m_pRadioButton[1]->down_box(FL_ROUND_DOWN_BOX);
    m_pRadioButton[1]->align(FL_ALIGN_RIGHT);
    m_pOKButton = new Fl_Button(w() - 3 * (DLG_BUTTON_WIDTH + DLG_BORDER),
				h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
				DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton = new Fl_Button(w() - 2 * (DLG_BUTTON_WIDTH + DLG_BORDER),
				    h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
				    DLG_BUTTON_WIDTH,
				    DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - 1 * (DLG_BUTTON_WIDTH + DLG_BORDER),
				  h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
				  DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);
    end();

    m_bSelection = bSelection;
    m_pRadioButton[m_bSelection == true ? 0 : 1]->value(1);

    // The DoModal method will show this dialog
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
ListByDlg::~ListByDlg()
{
}


//--------------------------------------------------------------//
// Run the modal dialog.                                        //
//--------------------------------------------------------------//
int
ListByDlg::DoModal()
{
    int nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

    if (nReturn == 1) {
	// OK button was pressed, update the selection
	m_bSelection = (m_pRadioButton[0]->value() == 1);
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
ListByDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_LISTBY_DLG);
}

--- NEW FILE: SchedulerCategoryDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler Category database class.                           //
//--------------------------------------------------------------//
#ifndef SCHEDULERCATEGORYDB_H_

#define SCHEDULERCATEGORYDB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "CategoryDB.h"
class SchedulerCategoryDB:public CategoryDB
{
  public:SchedulerCategoryDB();
    // Constructor
    ~SchedulerCategoryDB();	// Destructor
    static SchedulerCategoryDB *GetSchedulerCategoryDB();	// Retrieve the static pointer
  private:static SchedulerCategoryDB *m_pThis;
    // One and only scheduler category object
};


#endif /*  */

--- NEW FILE: DatePickerDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Date Picker Dialog.                                          //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include <FL/Fl_Return_Button.H>
#include "DatePickerDlg.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT(nType) (DLG_BUTTON_HEIGHT+DLG_BORDER+DatePicker::GetHeight(nType))
#define DLG_WIDTH (2*DLG_BORDER+DatePicker::GetWidth())


//--------------------------------------------------------------//
// Dialog titles based on the type of the dialog.  These must   //
// be in the same order as the Datepicker::Type enumeration.    //
//--------------------------------------------------------------//
const char *
    DatePickerDlg::m_pszTitle[3] = {
    "Select Date",
    "Select Week",
    "Select Month",
};


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
DatePickerDlg::DatePickerDlg(time_t nTime,
			     DatePicker::Type nType, Fl_Widget * pParent)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT(nType)) >> 1),
	  DLG_WIDTH,
	  DLG_HEIGHT(nType),
	  _(nType >= 0
	      && nType < 3 ? m_pszTitle[nType] : m_pszTitle[0]))
{
    int nPushButtonWidth = (DatePicker::GetWidth() - 2 * DLG_BORDER) / 3;

    // Set the preselected date
    m_nTime = nTime;

    // Set the dialog type
    if (nType < 0 || nType >= 3) {
	// Reset to daily
	nType = DatePicker::Daily;
    }

    m_pDatePicker = new DatePicker(DLG_BORDER, DLG_BORDER, nType, nTime);

    // Create the buttons
    m_pOKButton = new Fl_Return_Button(DLG_BORDER,
				       h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
				       w() - 4 * DLG_BORDER -
				       2 * nPushButtonWidth,
				       DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton =
	new Fl_Button(w() - 2 * (nPushButtonWidth + DLG_BORDER),
		      h() - DLG_BUTTON_HEIGHT - DLG_BORDER, nPushButtonWidth,
		      DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pTodayButton = new Fl_Button(w() - nPushButtonWidth - DLG_BORDER,
				   h() - (DLG_BUTTON_HEIGHT + DLG_BORDER),
				   nPushButtonWidth,
				   DLG_BUTTON_HEIGHT, _("&Today"));
    m_pTodayButton->callback(TodayButtonCallback);

    // Finish the dialog
    end();

    // The DoModal method will show this dialog
}


//--------------------------------------------------------------//
// Run the modal dialog.                                        //
//--------------------------------------------------------------//
int
DatePickerDlg::DoModal()
{
    int nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

    if (nReturn == 1) {
	// OK button was pressed, get the updated note
	m_nTime = m_pDatePicker->GetDate();
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Process a click on the Today button.                         //
//--------------------------------------------------------------//
void
DatePickerDlg::TodayButtonCallback(Fl_Widget * pWidget, void *pUserData)
{
    DatePickerDlg *pThis =
	reinterpret_cast < DatePickerDlg * >(pWidget->parent());
    time_t nToday = time(NULL);

    pThis->m_pDatePicker->SetDate(nToday);
}

--- NEW FILE: ToolbarButton.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for a button on a toolbar object.                      //
//--------------------------------------------------------------//
#ifndef TOOLBARBUTTON_H_

#define TOOLBARBUTTON_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <cstdio>
#include <string>
#include <FL/Fl_Button.H>
#include <FL/Fl_Pixmap.H>
using namespace std;

#define TOOLBAR_BUTTON_WIDTH 22
class ToolbarButton:public Fl_Button
{
  public:ToolbarButton(int nX,
		  // Constructor
		  int nY, int nImage, int nDisabledImage,
		  const char *pszTooltip);
     ~ToolbarButton();		// Destructor
    inline void DoCallback()	// Do the real callback with the parent as the sending widget
    {
	(*m_pfnCallback) (parent(), NULL);
    }
    void Enable(bool bEnable = true);	// Enable or disable this button
    inline int GetNormalImage() const	// Get the normal image index
    {
	return (m_nNormalImage);
    }
    inline static int GetWidth()	// Get the default button width
    {
	return (TOOLBAR_BUTTON_WIDTH);
    }
    inline void SetCallback(Fl_Callback * pfnCallback)	// Set the real callback
    {
	m_pfnCallback = pfnCallback;
    }
  private:bool m_bEnabled;	// Is this button enabled or not
    Fl_Callback *m_pfnCallback;	// The real callback
    Fl_Pixmap *m_pPixmap;	// The image for this button
    int m_nNormalImage;		// The normal image
    int m_nDisabledImage;	// The disabled image
    std::string m_strTooltip;	// The tooltip text
};


#endif /*  */

--- NEW FILE: AddressBookList.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the Address Book List.                             //
//--------------------------------------------------------------//
#ifndef ADDRESSBOOKLIST_H_

#define ADDRESSBOOKLIST_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "AddressBookDB.h"
#include "Messages.h"
#include "TableBase.h"

#define ADDRESSBOOK_LARGE_COLUMNS 5
#define ADDRESSBOOK_SMALL_COLUMNS 3
typedef void (*ADDRESS_BOOK_CALLBACK) (int nRow, int nCol);
class AddressBookList:public TableBase
{
  public:AddressBookList(int nX,
		    // Constructor
		    int nY, int nWidth, int nHeight, bool bSmall);
     ~AddressBookList();	// Destructor
    void Filter(int nCategory);	// Filter the displayed rows by category (-1 = all categories)
    inline bool GetListBy() const	// Get the List By option
    {
	return (m_bByLastName);
    }
    inline int GetRealRow()	// Get the real row number of the currently selected row
    {
	return (AddressBookDB::GetAddressBookDB()->
		FindRealRow(row(), m_vpRow));
    }
    int Message(PixilDTMessage nMessage,	// Process a message from the parent widget
		int nInfo);
    void Print();		// Print the address book as currently sorted
    void Refresh(int nID = -1);	// Refresh this list
    bool Search(const char *pszValue);	// Search for a row beginning with...
    void SelectRow(int nRealRow);	// Select a row in the list and inform the parent of the selection
    inline void SetDoubleClick(ADDRESS_BOOK_CALLBACK pfnCallback)	// Process a double click on a non-icon column for a short display
    {
	m_pfnDoubleClick = pfnCallback;
    }
    inline void SetListBy(bool bByLastName)	// Set the List By option
    {
	m_bByLastName = bByLastName;
    }
  protected:void CalculateColumnWidths(int nWidth);
    // Recalculate column widths
    void DoubleClick(int nRow,	// Process a double click over a row
		     int nCol);
    Fl_Pixmap *GetIconValue(int nRow,	// Get the icon for an icon column
			    int nCol);
    string GetStringValue(int nRow,	// Get the value of a column
			  int nCol);
    void IconClick(int nRow,	// Process a left mouse click over an icon column
		   int nCol);
    void LeftClick(int nRow,	// Process a left mouse click over a non-icon column
		   int nCol);
    void RightClick(int nRow,	// Process a right mouse click anywhere
		    int nCol);
  private:ADDRESS_BOOK_CALLBACK m_pfnDoubleClick;
    // Process a double click from a short display
    static const bool m_bLargeIconColumns[ADDRESSBOOK_LARGE_COLUMNS];	// Large icon columns
    static const bool m_bSmallIconColumns[ADDRESSBOOK_SMALL_COLUMNS];	// Small icon columns
    bool m_bByLastName;		// Display by last name or by company name
    bool m_bSmall;		// Small list or not
    static char m_szCategory[16];	// Category being filtered on
    Fl_Pixmap *m_pNotesIcon;	// Notes icon used by all rows
    int m_nCategory;		// Category used for filtering (-1 for all)
    ROW_VECTOR m_vpRow;		// Private copy of pointers to address book rows in the current sort order
    static bool SortCategory1(NxDbRow * pRow1,	// Sort by last name, first name and filter by category
			      NxDbRow * pRow2);
    static bool SortCategory2(NxDbRow * pRow1,	// Sort by company, last name and filter by category
			      NxDbRow * pRow2);
    static bool SortCompare1(NxDbRow * pRow1,	// Sort by last name, first name
			     NxDbRow * pRow2);
    static bool SortCompare2(NxDbRow * pRow1,	// Sort by company, last name
			     NxDbRow * pRow2);
};


#endif /*  */

--- NEW FILE: LeftGroup.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the left portion of the main window for PixilDT.   //
//--------------------------------------------------------------//
#ifndef LEFTGROUP_H_

#define LEFTGROUP_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Group.H>
#include "ImageBox.h"
#include "Messages.h"
class LeftGroup:public Fl_Group
{
  public:LeftGroup(int nX,	// Constructor
	      int nY, int nWidth, int nHeight);
    int Message(PixilDTMessage nMessage,	// Process a message from the parent widget
		int nInfo);
    void Notify(PixilDTMessage nMessage,	// Process a notification from a child widget
		int nInfo);
};


#endif /*  */

--- NEW FILE: NxDbColumn.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class Used to represent a column in an NxDb database.        //
//--------------------------------------------------------------//
#ifndef NXDBCOLUMN_H_

#define NXDBCOLUMN_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <string>
using namespace std;
class NxDbColumn
{
  public:enum DataType
    { DataTypeChar = 'c', DataTypeInt16 = 'i', DataTypeInt32 = 'l',
    };
      NxDbColumn(int nType,	// Constructor
		 int nMaxLength = 1);
    inline NxDbColumn(const NxDbColumn & Other)	// Copy constructor
    {
	m_Union.m_pszString = NULL;	// Avoid GPF
	*this = Other;
    }
     ~NxDbColumn();		// Destructor
    NxDbColumn & operator=(const NxDbColumn & Other);	// Assignment operator
    void Clear();		// Clear this column
    string Export();		// Export this data as a string
    int GetIntValue() const;	// Get the value of this column as an integer
    string GetStringValue() const;	// Get the value of this column as a string
    void Import(const string & strData);	// Import an escaped string
    void Output(unsigned char *ucPtr);	// Output the contents of this column
    void SetStringValue(const char *pszValue);	// Set the initial value of the field
    bool SetValue(const char *pszValue);	// Set to a string value
    bool SetValue(int nValue);	// Set to an integer value
    bool SetValue(const string & strValue);	// set to a string value
    void SetType(int nType,	// Reset the type of the column
		 int m_nMaxLength = 1);
  private:unsigned char m_ucType;
    // The type of field stored here
    unsigned int m_nMaxLength;	// Maximum array size (for strings includes the null terminator)
    union tagField		// Three types of fields allowed
    {
	int m_nInt;		// 32 bit integer - also contains 16 bit integers
	char *m_pszString;	// Character string (string class cannot be used in a union)
    }
    m_Union;
};


#endif /*  */

--- NEW FILE: NoteDBDef.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Notes database definition fields.                            //
//--------------------------------------------------------------//
#ifndef NOTEDBDEF_H_

#define NOTEDBDEF_H_

// Note database
field noteFields[] = {
    {
     'i', 1, 0}
    , {
       'i', 1, 0}
    ,				/* note category */
    {
     'c', NOTE_FILE_LEN, 0}
    ,				/* key note name */
    {
     'c', NOTE_TITLE_LEN, 0}
    ,				/* note title */
    {
     'i', 1, 0}
    ,				/* archive 1=yes 0=no */
    {
     0}
};

fildes noteFile = {		/* system file */
    0, 0, 0,			/* database file */
    "dbf",			/* extension */
    NOTE_NUM_FIELDS,		/* nfields */
    &noteFields[0]		/* fieldlist */
};


#endif /*  */

--- NEW FILE: NoteEditorDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Note Editor Dialog.                                          //
//--------------------------------------------------------------//
#ifndef NOTEEDITORDLG_H_

#define NOTEEDITORDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Button.H>
#include <FL/Fl_Window.H>
#include "Note.h"
#include "NoteEditor.h"
class NoteEditorDlg:public Fl_Window
{
  public:NoteEditorDlg(Note * pNote,
		  // Constructor
		  Fl_Widget * pParent);
    ~NoteEditorDlg();		// Destructor
    void DestroyNote()		// Destroy the note saved as a part of this object
    {
	delete m_pNote;
    }
    int DoModal();		// Run the modal dialog
    inline Note *GetNote() const	// Get the note object
    {
	return (m_pNote);
    }
  private:  Fl_Button * m_pCancelButton;
    // The Cancel button
    Fl_Button *m_pHelpButton;	// The Help Button
    Fl_Button *m_pOKButton;	// The OK button
    Note *m_pNote;		// The note (after call to DoModal)
    NoteEditor *m_pNoteEditor;	// Note editor
    static void OnHelpButton(Fl_Widget * pWidget,	// Process click on the Help button
			     void *pUserData);
};


#endif /*  */

--- NEW FILE: CategoryEditorList.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Category Editor List widget.                                 //
//--------------------------------------------------------------//
#include <FL/fl_draw.H>
#include <FL/forms.H>

#include "CategoryEditor.h"
#include "CategoryEditorList.h"
#include "FLTKUtil.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
CategoryEditorList::CategoryEditorList(int nX,	// Constructor
				       int nY,
				       int nWidth,
				       int nHeight, CategoryDB * pDB)
    :
Flv_List(nX, nY, nWidth, nHeight)
{
    Fl_Color cDeadSpaceColor = FL_WHITE;

    m_pDB = pDB;
    m_nCurrentRow = -1;
    selection_color(FL_SELECTION_COLOR);
    color(FL_WHITE);
    dead_space_color(cDeadSpaceColor);
    callback(Callback);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
CategoryEditorList::~CategoryEditorList()
{
}


//--------------------------------------------------------------//
// FLTK callback                                                //
//--------------------------------------------------------------//
void
CategoryEditorList::Callback(Fl_Widget * pWidget, void *pUserData)
{
    CategoryEditorList *pThis =
	dynamic_cast < CategoryEditorList * >(pWidget);

    // Check if the selected row number changed
    if (pThis->row() >= 0 && pThis->row() != pThis->m_nCurrentRow) {
	CategoryEditor::ButtonStatus nStatus;

	// The selection has changed
	pThis->m_nCurrentRow = pThis->row();

	// Is it the "unfiled" selection ?
	if (pThis->m_nCurrentRow == 0) {
	    // Disable the delete button
	    nStatus = CategoryEditor::Disable;
	} else {
	    // Enable the delete button
	    nStatus = CategoryEditor::Enable;
	}
	dynamic_cast < CategoryEditor * >(pThis->parent())->Notify(nStatus);
    }
}


//--------------------------------------------------------------//
// Draw a row - virtual callback, reason why this class exists  //
// as a distinct class...                                       //
//--------------------------------------------------------------//
void
CategoryEditorList::draw_row(int nOffset,
			     int &nX,
			     int &nY, int &nWidth, int &nHeight, int nRow)
{
    Flv_Style s;

    Flv_List::draw_row(nOffset, nX, nY, nWidth, nHeight, nRow);
    get_style(s, nRow);

    // Change the foreground color based on row selecton
    s.foreground((Fl_Color) (nRow == row()? FL_WHITE : FL_BLACK));
    fl_color(s.foreground());

    // Now draw the text
    fl_draw(m_pDB->GetStringValue(nRow, CAT).c_str(),
	    nX - nOffset, nY, nWidth, nHeight, s.align());
}


//--------------------------------------------------------------//
// Handle events.                                               //
//--------------------------------------------------------------//
int
CategoryEditorList::handle(int nEvent)
{
    static const Fl_Menu_Item menuPopup[] = {
	{N_("Delete ")},
	{N_("Rename "), 0, 0, 0, FL_MENU_DIVIDER},
	{N_("New Category")},
	{NULL},
    };
    int nReturn = Flv_List::handle(nEvent);
    int nSelection;

    // Get right mouse button events
    switch (nEvent) {
    case FL_PUSH:
	if (Fl::event_button() == FL_RIGHT_MOUSE) {
	    nReturn = 1;	// Get the FL_RELEASE event as well
	}
	break;

    case FL_RELEASE:
	int nRow = get_row(Fl::event_x(), Fl::event_y());
	string strDelete;
	string strRename;

	if (Fl::event_button() == FL_RIGHT_MOUSE) {
	    // Show a menu based on the position of the mouse
	    if (nRow >= 1) {
		// Not on a title and not on the first ("unfiled") category
		// Show all selections on the pop-up menu
		nSelection =
		    DoPopupMenu(menuPopup, Fl::event_x(), Fl::event_y());
	    } else {
		// Show a menu with only a "New Category" selection
		nSelection =
		    DoPopupMenu(&menuPopup[2], Fl::event_x(), Fl::event_y());
		if (nSelection >= 0) {
		    // Correct for the two missing selections in the menu
		    nSelection += 2;
		}
	    }

	    // Perform the requested action
	    if (nSelection >= 0) {
		int nRow = get_row(Fl::event_x(), Fl::event_y());
		switch (nSelection) {
		case 0:	// Delete this category
		    ((CategoryEditor *) parent())->DeleteCategory(nRow);
		    break;

		case 1:	// Rename this category
		    ((CategoryEditor *) parent())->RenameCategory(nRow);
		    break;

		case 2:	// Insert a new category
		    ((CategoryEditor *) parent())->NewCategory();
		}
	    }
	    // Eat this event anyway
	    nReturn = 1;
	}
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Refresh this list from the data base                         //
//--------------------------------------------------------------//
void
CategoryEditorList::Refresh()
{
    // Sort the database by key
    m_pDB->Sort(CATID);

    // Cause the list to be redrawn
    rows(m_pDB->NumUndeletedRecs());
    redraw();
}

--- NEW FILE: ToDoListDBDef.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// ToDo List database definition fields.                        //
//--------------------------------------------------------------//
#ifndef NOTEDBDEF_H_

#define NOTEDBDEF_H_

// Contacts
field tdFields[] = {
    {
     'i', 1, 0}
    ,				// Field 0:Id
    {
     'i', 1, 0}
    ,				//       1:CategoryId
    {
     'i', 1, 0}
    ,				//       2:Complete
    {
     'i', 1, 0}
    ,				//       3:Priority
    {
     'c', TODO_TITLE_LEN, 0}
    ,				//       4:Title  
    {
     'c', TODO_DESC_LEN, 0}
    ,				//       5:File Name
    {
     'l', 1, 0}
    ,				//       6:time
    {
     0}
};


// Database
fildes tdFile = {		// system file
    0, 0, 0,			// database file
    "dbf",			// extension
    7,				// nfields
    &tdFields[0]		// fieldlist
};


#endif /*  */

--- NEW FILE: NxDb0009.txt ---
td_category
#1 0,"Unfiled"
#2 1,"Business"
#3 2,"Personal"

--- NEW FILE: ScheduleHours.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Schedule Hours displayed to the left of a day's appointments //
//--------------------------------------------------------------//
#include "config.h"
#include <cstdio>
#include <FL/fl_draw.H>
#include "PixilDT.h"
#include "ScheduleHours.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
ScheduleHours::ScheduleHours(int nX, int nY, int nWidth, int nHourHeight)
    :
Fl_Box(nX, nY, nWidth, 24 * nHourHeight)
{
    m_nHourHeight = nHourHeight;
    labelfont(FL_HELVETICA);
    labelsize((4 * labelsize()) / 5);
    box(FL_BORDER_BOX);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
ScheduleHours::~ScheduleHours()
{
}


//--------------------------------------------------------------//
// Override the virtual draw function                           //
//--------------------------------------------------------------//
void
ScheduleHours::draw()
{
    char szLabel[24];
    int i;
    int nDashWidth;
    int nHeight;
    int nHour;
    int nWidth;
    int nX;
    int nY;
    string strAM;
    string strPM;

    // Get the wording for AM/PM
    PixilDT::GetAMPM(strAM, strPM);

    // Do the base widget stuff
    draw_box();
    draw_label();

    // Now do the custom stuff
    fl_font(labelfont(), labelsize());
    fl_color(FL_BLACK);

    // Get the width of the small line
    fl_measure("a", nDashWidth, nHeight);

    // Draw each hour's text
    for (i = 0; i < 24; ++i) {
	// Draw each hour as needed
	if (strAM.length() != 0) {
	    // Twelve hour clock
	    nHour = i % 12;
	    if (nHour == 0) {
		nHour = 12;
	    }
	    sprintf(szLabel,
		    "%d%c00%s",
		    nHour,
		    PixilDT::GetTimeSeparator(),
		    i == 0 ? strAM.c_str() : i == 12 ? strPM.c_str() : "");
	} else {
	    // 24 hour clock
	    sprintf(szLabel, "%d%c00", i, PixilDT::GetTimeSeparator());
	}

	// Get the size of the label
	nWidth = w();
	nHeight = h() / 24;
	fl_measure(szLabel, nWidth, nHeight);

	// Determine where to draw the label
	nX = x() + (w() - nWidth) / 2;
	nY = y() + i * m_nHourHeight + (m_nHourHeight + nHeight) / 2 -
	    fl_descent();
	fl_draw(szLabel, nX, nY);

	// Draw the small line
	nHeight = y() + i * m_nHourHeight + (m_nHourHeight >> 1);
	fl_line(x() + w() - nDashWidth, nHeight, x() + w() - 1, nHeight);

	// Draw the separator line
	if (i != 24 - 1) {
	    nHeight = y() + (i + 1) * m_nHourHeight;
	    fl_line(x(), nHeight, x() + w() - 1, nHeight);
	}
    }
}

--- NEW FILE: NxDb0004.txt ---
add_custfields
#1 0,"Custom1"
#2 1,"Custom2"
#3 2,"Custom3"
#4 3,"Custom4"

--- NEW FILE: AddressBookDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Address Book Dialog.                                         //
//--------------------------------------------------------------//
#ifndef ADDRESSBOOKDLG_H_

#define ADDRESSBOOKDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Window.H>
#include "NoteEditor.h"
class AddressBookDlg:public Fl_Window
{
  public:AddressBookDlg(int nRow,
		   // Constructor
		   Fl_Widget * pParent);
     ~AddressBookDlg();		// Destructor
    int DoModal();		// Run the modal dialog
    inline int GetRecno() const	// Get the record number just updated/inserted
    {
	return (m_nRecno);
    }
  private:  Fl_Box * m_pMessage;
    // Static message
    Fl_Button *m_pCancelButton;	// The Cancel button
    Fl_Button *m_pHelpButton;	// The Help Button
    Fl_Button *m_pOKButton;	// The OK button
    Fl_Button *m_pRadioButton[7];	// Show radio buttons
    Fl_Choice *m_pCategory;	// Category Choice widget
    Fl_Choice *m_pInfoChoice[7];	// Info field choices
    Fl_Group *m_pPage[3];	// Tab pages
    Fl_Input *m_pAddress;	// Address widget
    Fl_Input *m_pAnniversary;	// Anniversary
    Fl_Input *m_pBirthday;	// Birthday
    Fl_Input *m_pCity;		// City widget
    Fl_Input *m_pCompany;	// The company widget
    Fl_Input *m_pCountry;	// Country widget
    Fl_Input *m_pCustom[4];	// Custom field widgets
    Fl_Input *m_pInfo[7];	// Info field widgets
    Fl_Input *m_pFirstName;	// The first name widget
    Fl_Input *m_pLastName;	// The last name widget
    Fl_Input *m_pPostalCode;	// Postal code widget
    Fl_Input *m_pRegion;	// Region widget
    Fl_Input *m_pTitle;		// The title widget
    Fl_Menu_Item *m_pTranslatedCategoryMenu;	// Menu for the category choice widget
    Fl_Menu_Item *m_pTranslatedMenu[7];	// Menus for each of m_pInfoChoice above
    Fl_Tabs *m_pTabs;		// The tab widget
    int m_nRecno;		// The record number just updated/inserted
    int m_nRow;			// Row in the Address Book database
    NoteEditor *m_pNoteEditor;	// Note editor
    string m_strCustomField[4];	// Custom field names
    void CreateCategoryChoice();	// Create the category choice widget
    void CreatePage1();		// Create the first tab page
    void CreatePage2();		// Create the first tab page
    void CreatePage3();		// Create the first tab page
    void FillInfoChoice(Fl_Choice * pChoice,	// Fill in an Info field choice widget
			int nIndex);
    static void OnHelpButton(Fl_Widget * pWidget,	// Process click on the Help button
			     void *pUserData);
};


#endif /*  */

--- NEW FILE: InputNotify.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// An Fl_Input widget that notifies its parent of changes.      //
//--------------------------------------------------------------//
#ifndef INPUTNOTIFY_H_

#define INPUTNOTIFY_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <string>
#include <FL/Fl_Input.H>
using namespace std;
class InputNotify:public Fl_Input
{
  public:InputNotify(int nX,	// Constructor
		int nY, int nWidth, int nHeight, const char *pszLabel,
		void (*pfnCallback) (Fl_Widget *, void *));
     ~InputNotify();		// Destructor
  protected:int handle(int nEvent);
    // Event handler
  private:  string m_strValue;
    // Last value of the widget, used to prevent too many callbacks
    void (*m_pfnCallback) (Fl_Widget *, void *);	// Callback function
};


#endif /*  */

--- NEW FILE: SchedulerDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Dialog for adding/updating Scheduler appointments.           //
//--------------------------------------------------------------//
#include "config.h"
#include <cstdlib>
#include <FL/fl_ask.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Return_Button.H>
#include "DatePickerDlg.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "Images.h"
#include "Messages.h"
#include "PixilDT.h"
#include "SchedulerChangeTypeDlg.h"
#include "SchedulerDB.h"
#include "SchedulerDlg.h"
#include "SchedulerRepeatDlg.h"
#include "SchedulerTimeDlg.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


#ifdef WIN32
#define max __max
#endif


#define DLG_HEIGHT       (9*DLG_BORDER+6*DLG_INPUT_HEIGHT+2*DLG_BUTTON_HEIGHT)
#define DLG_INDENT       (DLG_BUTTON_WIDTH+2*DLG_BORDER)
#define DLG_WIDTH        (DLG_INDENT+2*DLG_BORDER+2*DLG_BUTTON_WIDTH+20)


//--------------------------------------------------------------//
// Constructor, nRow is the row number in the Scheduler         //
// database as currently sorted or a -1 if this is to be a new  //
// row.                                                         //
//--------------------------------------------------------------//
SchedulerDlg::SchedulerDlg(int nRow, time_t nDate, Fl_Widget * pParent)
    :
Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Edit Event"))
{
    static const char *ppszTimeUnits[3] = {
	N_("Minutes Before"),
	N_("Hours Before"),
	N_("Days before"),
    };
    Fl_Box *pBox;
    int nToHeight;
    int nToWidth;
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();
    string strAm;
    string strPm;

    // Get the strings used for AM and PM
    PixilDT::GetAMPM(strAm, strPm);

    // Get the record number for this Scheduler key
    if (nRow < 0) {
	// New row
	m_nRow = -1;
    } else {
	m_nRow = nRow;
    }

    // Get the width of the word "to"
    fl_font(labelfont(), labelsize());
    fl_measure(_("t&o"), nToWidth, nToHeight);

    // Create the dialog widgets
    m_pDescription = new Fl_Multiline_Input(DLG_INDENT,
					    DLG_BORDER,
					    DLG_WIDTH - DLG_BORDER -
					    DLG_INDENT, 3 * DLG_INPUT_HEIGHT,
					    _("Description:"));
    m_pDescription->maximum_size(pSchedulerDB->GetColumnSize(SCHED_DESC));
    m_pStartTime = new Fl_Input(DLG_INDENT,
				2 * DLG_BORDER + 3 * DLG_INPUT_HEIGHT,
				(DLG_WIDTH - 3 * DLG_BORDER - nToWidth -
				 DLG_INDENT - IMAGE_BUTTON_WIDTH) / 2,
				DLG_INPUT_HEIGHT, _("Time:"));
    m_pStartTime->maximum_size(6 + max(strAm.length(), strPm.length()));
    m_pEndTime =
	new Fl_Input(DLG_INDENT + nToWidth + DLG_BORDER + m_pStartTime->w(),
		     2 * DLG_BORDER + 3 * DLG_INPUT_HEIGHT, m_pStartTime->w(),
		     DLG_INPUT_HEIGHT, _("to"));
    m_pEndTime->maximum_size(6 + max(strAm.length(), strPm.length()));
    m_pTimeButton = new Fl_Button(w() - DLG_BORDER - IMAGE_BUTTON_WIDTH,
				  2 * DLG_BORDER + 3 * DLG_INPUT_HEIGHT,
				  IMAGE_BUTTON_WIDTH, IMAGE_BUTTON_HEIGHT);
    m_pTimePixmap = Images::GetTimeIcon();
    m_pTimePixmap->label(m_pTimeButton);
    m_pTimeButton->callback(OnTimeButton);
    m_pDate = new Fl_Input(DLG_INDENT,
			   3 * DLG_BORDER + 4 * DLG_INPUT_HEIGHT,
			   (DLG_WIDTH - 3 * DLG_BORDER - DLG_INDENT -
			    IMAGE_BUTTON_WIDTH) / 2, DLG_INPUT_HEIGHT,
			   _("Date:"));
    m_pDate->maximum_size(10);
    m_pDayOfWeek = new Fl_Output(DLG_INDENT + DLG_BORDER + m_pDate->w(),
				 3 * DLG_BORDER + 4 * DLG_INPUT_HEIGHT,
				 m_pDate->w(), DLG_INPUT_HEIGHT);
    m_pDayOfWeek->color(FL_GRAY);
    m_pDayOfWeek->textfont(FL_HELVETICA_BOLD);
    m_pDayOfWeek->textsize((4 * labelsize()) / 5);
    m_pDateButton = new Fl_Button(w() - DLG_BORDER - IMAGE_BUTTON_WIDTH,
				  3 * DLG_BORDER + 4 * DLG_INPUT_HEIGHT,
				  IMAGE_BUTTON_WIDTH, IMAGE_BUTTON_HEIGHT);
    m_pDatePixmap = Images::GetCalendarIcon();
    m_pDatePixmap->label(m_pDateButton);
    m_pDateButton->callback(OnDateButton);
    pBox = new Fl_Box(DLG_BORDER,
		      4 * DLG_BORDER + 5 * DLG_INPUT_HEIGHT,
		      DLG_INDENT - DLG_BORDER,
		      DLG_INPUT_HEIGHT, _("Repeat:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    m_pRepeatButton =
	new Fl_Button(DLG_INDENT, 4 * DLG_BORDER + 5 * DLG_INPUT_HEIGHT,
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, _("None..."));
    m_pRepeatButton->callback(OnRepeatButton);
    pBox = new Fl_Box(DLG_BORDER,
		      5 * DLG_BORDER + 5 * DLG_INPUT_HEIGHT +
		      DLG_BUTTON_HEIGHT, DLG_INDENT - DLG_BORDER,
		      DLG_INPUT_HEIGHT);
    pBox->label(_("Alarm:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    m_pAlarmButton =
	new Fl_Check_Button(DLG_INDENT,
			    5 * DLG_BORDER + 5 * DLG_INPUT_HEIGHT +
			    DLG_BUTTON_HEIGHT, DLG_RADIO_SIZE,
			    DLG_INPUT_HEIGHT);
    m_pAlarmButton->callback(OnAlarm);
    m_pAlarmButton->type(FL_TOGGLE_BUTTON);
    m_pAlarmButton->down_box(FL_ROUND_DOWN_BOX);
    m_pInterval = new SpinInput(DLG_INDENT + DLG_RADIO_SIZE + DLG_BORDER, 5 * DLG_BORDER + 5 * DLG_INPUT_HEIGHT + DLG_BUTTON_HEIGHT, 3 * labelsize() + IMAGE_BUTTON_WIDTH, DLG_INPUT_HEIGHT, NULL, 2,	// Maximum size
				0,	// Minimum value
				99);	// Maximum value
    m_pInterval->value(5);	// Default to 5 minutes
    m_pTimeUnit =
	new Fl_Choice(DLG_INDENT + DLG_RADIO_SIZE + 3 * labelsize() +
		      IMAGE_BUTTON_WIDTH + 2 * DLG_BORDER,
		      5 * DLG_BORDER + 5 * DLG_INPUT_HEIGHT +
		      DLG_BUTTON_HEIGHT,
		      DLG_WIDTH - (DLG_INDENT + DLG_RADIO_SIZE +
				   3 * labelsize() + IMAGE_BUTTON_WIDTH +
				   3 * DLG_BORDER), DLG_INPUT_HEIGHT);
    m_pTimeUnitMenu = CreateChoice(3, ppszTimeUnits, true);
    m_pTimeUnit->value(0);	// Default to 5 minutes
    m_pTimeUnit->menu(m_pTimeUnitMenu);

    // Create the buttons
    m_pOKButton =
	new Fl_Return_Button(w() - 3 * DLG_BUTTON_WIDTH - 3 * DLG_BORDER,
			     h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
			     DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton =
	new Fl_Button(w() - 2 * DLG_BUTTON_WIDTH - 2 * DLG_BORDER,
		      h() - DLG_BORDER - DLG_BUTTON_HEIGHT, DLG_BUTTON_WIDTH,
		      DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				  h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
				  DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);

    end();

    // Save the selected date
    m_nDate = nDate;

    // Get the initial values for the data
    if (m_nRow == -1) {
	time_t nEndTime;
	time_t nStartTime;
	struct tm *pTm;

	// New row, set the date to the requested date
	m_pDate->value(::FormatDate(nDate).c_str());
	m_pDayOfWeek->value(::FormatDayOfWeek(nDate).c_str());

	// Initialize the repetition settings
	pTm = localtime(&nDate);
	pTm->tm_sec = 0;
	pTm->tm_min = 0;
	if (pTm->tm_hour < 23) {
	    ++pTm->tm_hour;
	}
	nEndTime = mktime(pTm);
	--pTm->tm_hour;
	nStartTime = mktime(pTm);
	m_pSchedulerRepeatData = new SchedulerRepeatData(nStartTime,
							 nEndTime);

	// Set the times in the dialog as well
	m_pStartTime->value(::FormatTime(nStartTime).c_str());
	m_pEndTime->value(::FormatTime(nEndTime).c_str());

	// Hide the alarm settings
	m_pInterval->hide();
	m_pTimeUnit->hide();
    } else {
	// Initialize these for possible use later
	m_pSchedulerRepeatData = pSchedulerDB->GetSchedulerRepeatData(nRow);

	// Existing row, set everything
	m_pDescription->value(pSchedulerDB->GetDescription(m_nRow).c_str());
	m_pStartTime->value(::FormatTime(pSchedulerDB->GetStartTime(m_nRow)).
			    c_str());
	m_pEndTime->value(::FormatTime(pSchedulerDB->GetEndTime(m_nRow)).
			  c_str());
	m_pDate->value(::FormatDate(m_nDate).c_str());
	m_pDayOfWeek->value(::FormatDayOfWeek(m_nDate).c_str());
	SetRepeatButton();

	// Process the alarm settings
	if (pSchedulerDB->GetAlarmFlags(m_nRow) != SCHED_NO_ALARM) {
	    // Use this row's alarm settings
	    m_pAlarmButton->value(1);
	    m_pInterval->value(pSchedulerDB->GetAlarmInterval(m_nRow));
	    m_pTimeUnit->value(pSchedulerDB->GetAlarmFlags(m_nRow));
	} else {
	    // Hide the alarm settings
	    m_pInterval->hide();
	    m_pTimeUnit->hide();
	}
    }

    // The DoModal method will call show on this window
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
SchedulerDlg::~SchedulerDlg()
{
    ::FreeTranslatedMenu(m_pTimeUnitMenu);
    delete m_pDatePixmap;
    delete m_pTimePixmap;
    delete m_pSchedulerRepeatData;
}


//--------------------------------------------------------------//
// Run the modal dialog                                         //
//--------------------------------------------------------------//
int
SchedulerDlg::DoModal()
{
    bool bGood = false;
    int nChangeType;
    int nResult;
    int nReturn = 1;
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();

    while (nReturn == 1 && bGood == false) {
	// Go run the dialog
	nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

	// Was the OK button pressed ?
	if (nReturn == 1) {
	    // Validate all fields
	    bGood = true;
	    if (strlen(m_pDescription->value()) == 0) {
		fl_alert(_
			 ("The Description is missing.  Please enter a Description."));
		bGood = false;
	    } else
		if ((nResult =::
		     ValidateTime(m_pStartTime->value(),
				  m_nStartTime)) != 0) {
		fl_alert(_("The Start Time is not a valid time:\n\n%s"),::
			 GetTimeError(nResult));
		bGood = false;
	    } else
		if ((nResult =::
		     ValidateTime(m_pEndTime->value(), m_nEndTime)) != 0) {
		fl_alert(_("The End Time is not a valid time:\n\n%s"),::
			 GetTimeError(nResult));
		bGood = false;
	    } else if (m_nStartTime >= m_nEndTime) {
		fl_alert(_("The End Time must be after the Start Time"));
		bGood = false;
	    } else if ((nResult =::ValidateDate(m_pDate->value(), m_nDate)) !=
		       0) {
		fl_alert(_("The Date is not a valid date:\n\n%s"),::
			 GetDateError(nResult));
		bGood = false;
	    }
	    // Update if all pased
	    if (bGood == true) {
		// Set to change the original record
		nChangeType = SCHEDULER_CHANGE_TYPE_ALL;

		// Create a new Scheduler record if needed
		if (m_nRow < 0) {
		    m_nRow = pSchedulerDB->Insert();
		} else {
		    // Updating an existing item, determine whether to ask
		    // about updating events in a repeating sequence or not.
		    if (pSchedulerDB->GetRepeatingFlag(m_nRow) == true) {
			// Something besides the description must have changed
			if (pSchedulerDB->
			    RepeatDataChanged(m_nRow,
					      m_pSchedulerRepeatData) == true
			    || pSchedulerDB->GetStartTime(m_nRow) !=
			    m_nStartTime + m_nDate
			    || pSchedulerDB->GetEndTime(m_nRow) !=
			    m_nEndTime + m_nDate
			    || (m_pAlarmButton->value() == 0
				&& pSchedulerDB->GetAlarmFlags(m_nRow) ==
				SCHED_NO_ALARM)
			    || (m_pAlarmButton->value() == 1
				&& (pSchedulerDB->GetAlarmFlags(m_nRow) !=
				    m_pTimeUnit->value()
				    || pSchedulerDB->
				    GetAlarmInterval(m_nRow) !=
				    m_pInterval->value()))) {
			    SchedulerChangeTypeDlg *pDlg =
				new SchedulerChangeTypeDlg(this, false);

			    // Ask about whether to change the current item only,
			    // the current item and future items or all items
			    if (pDlg->DoModal() == 1) {
				nChangeType = pDlg->GetChangeType();
			    } else {
				// Set no changes wanted - the user cancelled the dialog
				nChangeType = SCHEDULER_CHANGE_TYPE_NONE;
			    }
			    delete pDlg;
			}
		    }
		}

		switch (nChangeType) {
		case SCHEDULER_CHANGE_TYPE_ALL:	// Change all repetitions
		    if (pSchedulerDB->GetRepeatType(m_nRow) !=
			m_pSchedulerRepeatData->GetRepeatType()) {
			// Remove any prior exceptions if changing the repetition type
			pSchedulerDB->RemoveExceptions(m_nRow);
		    }
		    SetFields(m_nRow);
		    break;

		case SCHEDULER_CHANGE_TYPE_CURRENT_FUTURE:	// Change current and future repetitions
		    // Make these repetitions end one day prior to the selected event
		    pSchedulerDB->
			EndRepetitions(m_nRow,::SubtractDays(m_nDate, 1));

		    // Add a new row to carry on from here
		    m_nRow = pSchedulerDB->Insert();
		    m_pSchedulerRepeatData->SetStartDate(m_nDate);
		    SetFields(m_nRow);
		    break;

		case SCHEDULER_CHANGE_TYPE_CURRENT_ONLY:	// Change only the current repetition
		    // Add a deleted exception for this date
		    pSchedulerDB->AddDeletedException(m_nRow, m_nDate);

		    // Add a new row for this exception date
		    m_nRow = pSchedulerDB->Insert();
		    m_pSchedulerRepeatData->SetNoRepetition();
		    m_pSchedulerRepeatData->SetStartDate(m_nDate);
		    SetFields(m_nRow);
		}

		// Save these changes
		pSchedulerDB->Save();

		// Notify everyone of these changes
		PixilDT::GetApp()->GetMainWindow()->
		    Notify(ADDRESS_BOOK_CHANGED, 0);
	    }
	}
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Process a click on the alarm radio button.                   //
//--------------------------------------------------------------//
void
SchedulerDlg::OnAlarm(Fl_Widget * pWidget, void *pUserData)
{
    Fl_Check_Button *pButton =
	reinterpret_cast < Fl_Check_Button * >(pWidget);
    SchedulerDlg *pThis =
	reinterpret_cast < SchedulerDlg * >(pWidget->parent());

    if (pButton->value() == 1) {
	// Show the other alarm fields
	pThis->m_pInterval->show();
	pThis->m_pTimeUnit->show();
    } else {
	// Hide the other alarm fields
	pThis->m_pInterval->hide();
	pThis->m_pTimeUnit->hide();
    }
}


//--------------------------------------------------------------//
// Date/Calendar button was clicked (static callback).          //
//--------------------------------------------------------------//
void
SchedulerDlg::OnDateButton(Fl_Widget * pWidget, void *pUserData)
{
    DatePickerDlg *pDlg;
    SchedulerDlg *pThis =
	reinterpret_cast < SchedulerDlg * >(pWidget->parent());
    time_t nDate;

    // Get the current date from the dialog
    if (::ValidateDate(pThis->m_pDate->value(), nDate) != 0) {
	// If bad, use the one from the data base
	if (pThis->m_nRow >= 0) {
	    // Get from an existing row
	    nDate =
		SchedulerDB::GetSchedulerDB()->GetStartTime(pThis->m_nRow);
	} else {
	    // This is a new row, use today
	    nDate = time(NULL);
	}
    }
    // Now run the dialog
    pDlg =
	new DatePickerDlg(nDate, DatePicker::Daily,
			  PixilDT::GetApp()->GetMainWindow());
    if (pDlg->DoModal() == 1) {
	// Get the new start and end times
	pThis->m_pDate->value(::FormatDate(pDlg->GetDate()).c_str());
	pThis->m_pDayOfWeek->value(::FormatDayOfWeek(pDlg->GetDate()).
				   c_str());
    }
    // Clean up
    delete pDlg;
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
SchedulerDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_SCHEDULER_DLG);
}


//--------------------------------------------------------------//
// Repeat button was clicked (static callback).                 //
//--------------------------------------------------------------//
void
SchedulerDlg::OnRepeatButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerDlg *pThis =
	reinterpret_cast < SchedulerDlg * >(pWidget->parent());
    SchedulerRepeatDlg *pDlg;

    // Now run the dialog
    pDlg = new SchedulerRepeatDlg(pThis->m_pSchedulerRepeatData,
				  PixilDT::GetApp()->GetMainWindow());
    if (pDlg->DoModal() == 1) {
	delete pThis->m_pSchedulerRepeatData;
	pThis->m_pSchedulerRepeatData =
	    new SchedulerRepeatData(pDlg->GetSchedulerRepeatData());
	pThis->SetRepeatButton();

	// Display the date in case it changed
	pThis->m_pDate->
	    value(::FormatDate(pThis->m_pSchedulerRepeatData->GetStartTime()).
		  c_str());
	pThis->m_pDayOfWeek->
	    value(::
		  FormatDayOfWeek(pThis->m_pSchedulerRepeatData->
				  GetStartTime()).c_str());
    }
    // Clean up
    delete pDlg;
}


//--------------------------------------------------------------//
// Time button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
SchedulerDlg::OnTimeButton(Fl_Widget * pWidget, void *pUserData)
{
    int nEndTime;
    int nStartTime;
    SchedulerDlg *pThis =
	reinterpret_cast < SchedulerDlg * >(pWidget->parent());
    SchedulerTimeDlg *pDlg;
    time_t nEndDate;
    time_t nStartDate;
    struct tm *pTm;

    // Get the current start time from the dialog
    if (::ValidateTime(pThis->m_pStartTime->value(), nStartTime) != 0) {
	// If the currently entered time is bad, use midnight
	nStartTime = 0;
    }
    // Get the current end time from the dialog
    if (::ValidateTime(pThis->m_pEndTime->value(), nEndTime) != 0) {
	// If the currently entered time is bad, use 5 minutes before midnight
	nEndTime = 24 * 60 * 60 - 5 * 60;
    }
    // Get the current date from the dialog
    if (::ValidateDate(pThis->m_pDate->value(), nStartDate) != 0) {
	// If bad, use the one from the data base
	if (pThis->m_nRow >= 0) {
	    // Get from an existing row
	    nStartDate =
		SchedulerDB::GetSchedulerDB()->GetStartTime(pThis->m_nRow);
	} else {
	    // This is a new row, use today
	    nStartDate = time(NULL);
	}
    }
    // Get current start date
    pTm = localtime(&nStartDate);
    pTm->tm_sec = 0;
    pTm->tm_min = (nStartTime % (60 * 60)) / 60;
    pTm->tm_hour = nStartTime / (60 * 60);
    nStartDate = mktime(pTm);

    // Get the current end date
    pTm->tm_min = (nEndTime % (60 * 60)) / 60;
    pTm->tm_hour = nEndTime / (60 * 60);
    nEndDate = mktime(pTm);

    // Now run the dialog
    pDlg =
	new SchedulerTimeDlg(nStartDate, nEndDate,
			     PixilDT::GetApp()->GetMainWindow());
    if (pDlg->DoModal() == 1) {
	// Get the new start and end times
	pThis->m_pStartTime->value(::FormatTime(pDlg->GetStartTime()).
				   c_str());
	pThis->m_pEndTime->value(::FormatTime(pDlg->GetEndTime()).c_str());
    }
    // Clean up
    delete pDlg;
}


//--------------------------------------------------------------//
// Move all dialog data to a data base row.                     //
//--------------------------------------------------------------//
void
SchedulerDlg::SetFields(int nRow)
{
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();

    pSchedulerDB->SetSchedulerRepeatData(nRow, m_pSchedulerRepeatData);
    pSchedulerDB->SetStartTime(nRow, m_nStartTime + m_nDate);
    pSchedulerDB->SetEndTime(nRow, m_nEndTime + m_nDate);
    pSchedulerDB->SetAllDayFlag(nRow, 0);
    pSchedulerDB->SetEntryType(nRow, 0);
    pSchedulerDB->SetDescription(nRow, m_pDescription->value());

    // Get the alarm settings
    if (m_pAlarmButton->value() == 1) {
	// Turn the alarm on
	pSchedulerDB->SetAlarmFlags(nRow, m_pTimeUnit->value());
	pSchedulerDB->SetAlarmInterval(nRow, m_pInterval->value());
    } else {
	// Turn the alarm off
	pSchedulerDB->SetAlarmFlags(nRow, SCHED_NO_ALARM);
	pSchedulerDB->SetAlarmInterval(nRow, 0);
    }
}


//--------------------------------------------------------------//
// Set the label on the repeat button.                          //
//--------------------------------------------------------------//
void
SchedulerDlg::SetRepeatButton()
{
    m_strRepeatLabel = m_pSchedulerRepeatData->GetRepeatTypeString();
    m_strRepeatLabel += _("...");
    m_pRepeatButton->label(m_strRepeatLabel.c_str());
}

--- NEW FILE: NoteDetails.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the Note Details.                                  //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "NoteDB.h"
#include "NoteDetails.h"
#include "NotesCategoryDB.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
NoteDetails::NoteDetails(int nX, int nY, int nWidth, int nHeight)
    :
Fl_Group(nX, nY, nWidth, nHeight)
{
    m_pTitlePrompt = new Fl_Box(x() + DLG_BORDER,
				y(),
				w() - 2 * DLG_BORDER,
				DLG_INPUT_HEIGHT, _("Description:"));
    m_pTitlePrompt->
	align(FL_ALIGN_LEFT | FL_ALIGN_BOTTOM | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    m_pTitle =
	new Fl_Input(x() + DLG_BORDER, y() + DLG_INPUT_HEIGHT + DLG_BORDER,
		     w() - 2 * DLG_BORDER, DLG_INPUT_HEIGHT);
    m_pTitle->maximum_size(NoteDB::GetNoteDB()->GetColumnSize(NOTE_DESC));
    m_pNoteEditor = new NoteEditor(x() + DLG_BORDER,
				   y() + 2 * DLG_INPUT_HEIGHT +
				   2 * DLG_BORDER, w() - 2 * DLG_BORDER,
				   h() - DLG_INPUT_HEIGHT -
				   3 * DLG_BUTTON_HEIGHT - 4 * DLG_BORDER,
				   false);
    m_pNoteEditor->SetDestroyNote(true);
    m_pCategoryPrompt = new Fl_Box(x() + DLG_BORDER,
				   y() + h() - 2 * DLG_BUTTON_HEIGHT -
				   DLG_BORDER,
				   w() - DLG_BUTTON_WIDTH - 2 * DLG_BORDER,
				   DLG_BUTTON_HEIGHT, _("Category:"));
    m_pCategoryChoice =
	new Fl_Choice(x() + w() - DLG_BUTTON_WIDTH - DLG_BORDER,
		      y() + h() - 2 * DLG_BUTTON_HEIGHT - DLG_BORDER,
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
    m_pCategoryMenu =
	NotesCategoryDB::GetNotesCategoryDB()->GetCategoryMenu(false);
    m_pCategoryChoice->menu(m_pCategoryMenu);
    m_pApplyButton = new Fl_Button(x() + w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				   y() + h() - DLG_BUTTON_HEIGHT,
				   DLG_BUTTON_WIDTH,
				   DLG_BUTTON_HEIGHT, _("&Apply"));
    m_pApplyButton->callback(OnApply);
    m_pApplyButton->deactivate();
    end();

    // Set that only the note text is resizable
    resizable(m_pNoteEditor);

    // Set that no note is being displayed
    m_nIndex = -1;
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
NoteDetails::~NoteDetails()
{
    FreeTranslatedMenu(m_pCategoryMenu);
}


//--------------------------------------------------------------//
// Display a note                                               //
//--------------------------------------------------------------//
void
NoteDetails::DisplayRow(int nRow, int nCategory)
{
    int nCategoryNo;
    int nRows;
    NoteDB *pNoteDB = NoteDB::GetNoteDB();

    // Get the number of records that should be in the list
    if (nCategory == -1) {
	nRows = pNoteDB->NumUndeletedRecs();
    } else {
	// Translate the category
	nCategoryNo =
	    NotesCategoryDB::GetNotesCategoryDB()->GetCategoryID(nCategory);
	nRows = pNoteDB->NumRecsByKey(NOTE_CAT, nCategoryNo);
    }

    // Enable everything if there are some rows
    if (nRows > 0) {
	// Enable all input objects
	Enable(true);

	// Change the display if this is a different row in the data base
	if (pNoteDB->GetIndex(nRow) != m_nIndex) {
	    // Save any outstanding changes
	    SaveChanges(true);

	    // Display this row (and destroy the older note object)
	    m_pTitle->value(pNoteDB->GetTitle(nRow).c_str());
	    nCategoryNo =
		NotesCategoryDB::GetNotesCategoryDB()->FindRow(CATID,
							       pNoteDB->
							       GetCategory
							       (nRow));
	    if (nCategoryNo < 0) {
		// Fix if bad category
		nCategoryNo = 0;
	    }
	    m_pCategoryChoice->value(nCategoryNo);
	    m_pNoteEditor->SetNote(pNoteDB->GetNote(nRow), true);

	    // Note the key-id being displayed
	    m_nIndex = pNoteDB->GetIndex(nRow);
	}
    } else {
	// Disable everything if there are no rows for the category choice
	Enable(false);
	m_nIndex = -1;
    }
}


//--------------------------------------------------------------//
// Enable or disable all input fields.                          //
//--------------------------------------------------------------//
void
NoteDetails::Enable(bool bEnable)
{
    if (bEnable == true) {
	// Activate everything
	m_pApplyButton->activate();
	m_pCategoryChoice->activate();
	m_pTitle->activate();
	m_pTitle->color(FL_WHITE);
    } else {
	// Deactivate everything
	m_pApplyButton->deactivate();
	m_pCategoryChoice->value(0);
	m_pCategoryChoice->deactivate();
	m_pTitle->value("");
	m_pTitle->deactivate();
	m_pTitle->color(FL_GRAY);
    }
    m_pNoteEditor->Enable(bEnable);
}


//--------------------------------------------------------------//
// Process a message from the parent widget                     //
//--------------------------------------------------------------//
int
NoteDetails::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case -1:			// Not implemented yet
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Apply changed to a note                                      //
//--------------------------------------------------------------//
void
NoteDetails::OnApply(Fl_Widget * pWidget, void *pUserData)
{
    // Save any changes without asking whether to do so or not
    ((NoteDetails *) (pWidget->parent()))->SaveChanges(false);
}


//--------------------------------------------------------------//
// Save any changes to the current note.  A return of 0         //
// indicates that changes were not saved at the user's request. //
//--------------------------------------------------------------//
int
NoteDetails::SaveChanges(bool bAsk)
{
    int nCategory;
    int nResult;
    int nReturn = 1;
    int nRow;
    Note *pNote;
    NoteDB *pNoteDB = NoteDB::GetNoteDB();

    // Find the current row
    nRow = pNoteDB->FindRow(NOTE_INDEX, m_nIndex);
    if (nRow >= 0) {
	// Has anything been changed
	nCategory =
	    NotesCategoryDB::GetNotesCategoryDB()->
	    GetCategoryID(m_pCategoryChoice->value());
	pNote = m_pNoteEditor->GetNote();
	if (pNoteDB->GetCategory(nRow) != nCategory
	    || strcmp(pNoteDB->GetTitle(nRow).c_str(), m_pTitle->value()) != 0
	    || pNote->IsChanged()) {
	    // Does the user want to save these changes
	    if (bAsk == true) {
		nResult =
		    fl_choice(_
			      ("Do you wish to save the changes to the Note:\n\n%s"),
			      fl_no, fl_yes, fl_cancel, m_pTitle->value());
		if (nResult == 1) {
		    // Yes button, indicate to save the data
		    nReturn = 1;
		} else if (nResult == 0) {
		    // No button, indicate to not save the data
		    nResult = 0;
		} else		//if (nResult==2)
		{
		    // Cancel button, indicate to not save and to cancel the calling function
		    nResult = 0;
		    nReturn = 0;
		}
	    } else {
		// Save without asking
		nResult = 1;
	    }

	    // Save the changes
	    if (nResult == 1) {
		pNoteDB->SetCategory(nRow, nCategory);
		pNoteDB->SetTitle(nRow, m_pTitle->value());
		pNote->Save();
		pNoteDB->SetFile(nRow, pNote->GetFileName().c_str());
		pNoteDB->Save();

		// OK button was pressed, refresh displays
		PixilDT::GetApp()->GetMainWindow()->Notify(NOTES_CHANGED, 0);
	    }
	}
    }

    return (nReturn);
}

--- NEW FILE: NxDbColumn.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class Used to represent a column in an NxDb database.        //
//--------------------------------------------------------------//
#include <cassert>
#include <climits>
#include <cstdio>
#include <FL/fl_ask.H>
#include <FL/x.H>
extern "C"
{
#include <file.h>
}
#include "NxDbColumn.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
NxDbColumn::NxDbColumn(int nType, int nMaxLength)
{
    m_ucType = nType;
    m_nMaxLength = nMaxLength;
    switch (m_ucType) {
    case DataTypeChar:		// String
	m_Union.m_pszString = NULL;
	break;

    default:			// Integer types
	m_Union.m_nInt = 0;
    }
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
NxDbColumn::~NxDbColumn()
{
    if (m_ucType == DataTypeChar) {
	delete[]m_Union.m_pszString;
    }
}


//--------------------------------------------------------------//
// Assignment operator.                                         //
//--------------------------------------------------------------//
NxDbColumn & NxDbColumn::operator=(const NxDbColumn & Other)
{
    // Copy only if needed
    if (this != &Other) {
	// Free up the old character string if needed
	if (m_ucType == DataTypeChar) {
	    delete[]m_Union.m_pszString;
	}
	// Copy to here
	m_ucType = Other.m_ucType;
	m_nMaxLength = Other.m_nMaxLength;
	switch (m_ucType) {
	case DataTypeChar:	// String
	    if (Other.m_Union.m_pszString != NULL) {
		m_Union.m_pszString =
		    new char[strlen(Other.m_Union.m_pszString) + 1];
		strcpy(m_Union.m_pszString, Other.m_Union.m_pszString);
	    } else {
		m_Union.m_pszString = NULL;
	    }
	    break;

	default:		// Integer types
	    m_Union.m_nInt = Other.m_Union.m_nInt;
	}
    }
    return (*this);
}


//--------------------------------------------------------------//
// Clear this column                                            //
//--------------------------------------------------------------//
void
NxDbColumn::Clear()
{
    switch (m_ucType) {
    case DataTypeChar:
	delete[]m_Union.m_pszString;
	m_Union.m_pszString = NULL;
	break;

    case DataTypeInt16:
    case DataTypeInt32:
	m_Union.m_nInt = 0;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown column type
#endif
	;
    }
}


//--------------------------------------------------------------//
// Export this column as a string.                              //
//--------------------------------------------------------------//
string
NxDbColumn::Export()
{
    char szData[16];
    string strReturn;

    switch (m_ucType) {
    case DataTypeChar:
	strReturn = m_Union.m_pszString;
	break;

    case DataTypeInt16:
    case DataTypeInt32:
	sprintf(szData, "%d", m_Union.m_nInt);
	strReturn = szData;
    }
    return (strReturn);
}


//--------------------------------------------------------------//
// Get the value of this column as an integer                   //
//--------------------------------------------------------------//
int
NxDbColumn::GetIntValue() const
{
    int nReturn;

    switch (m_ucType) {
    case DataTypeChar:		// Character string
#ifdef DEBUG
	assert(false);		// cannot get the integer value of a string
#endif
	nReturn = 0;
	break;

    case DataTypeInt16:
    case DataTypeInt32:
	nReturn = m_Union.m_nInt;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown data type
#endif
	;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Get the value of this column as a string.                    //
//--------------------------------------------------------------//
string
NxDbColumn::GetStringValue() const
{
    string strReturn;

    switch (m_ucType) {
    case DataTypeChar:		// Character string
	if (m_Union.m_pszString != NULL) {
	    strReturn = m_Union.m_pszString;
	}
	break;

    case DataTypeInt16:
    case DataTypeInt32:
	char szString[16];

	sprintf(szString, "%d", m_Union.m_nInt);
	strReturn = szString;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown data type
#endif
	;
    }
    return (strReturn);
}


//--------------------------------------------------------------//
// Import an escaped string.                                    //
//--------------------------------------------------------------//
void
NxDbColumn::Import(const string & strData)
{
    int nChar;
    string strData2;
    unsigned int nOffset;

    switch (m_ucType) {
    case DataTypeChar:
	// Unescape the string
	if (strData[0] == '\"' && strData[strData.length() - 1] == '\"') {
	    nOffset = 1;
	    while (nOffset < strData.length() - 2) {
		if (strData[nOffset] == '\\') {
		    // Escape sequence
#ifdef DEBUG
		    assert(nOffset < strData.length() - 3);	// Single backslash at end of string
#endif
		    switch (strData[nOffset + 1]) {
		    case 'a':
			strData2 += '\a';
			break;

		    case 'b':
			strData2 += '\b';
			break;

		    case 'f':
			strData2 += '\f';
			break;

		    case 'n':
			strData2 += '\n';
			break;

		    case 'r':
			strData2 += '\r';
			break;

		    case 't':
			strData2 += '\t';
			break;

		    case 'v':
			strData2 += '\v';
			break;

		    case '\'':
			strData2 += '\'';
			break;

		    case '\"':
			strData2 += '\"';
			break;

		    case '\\':
			strData2 += '\\';
			break;

		    case 'x':
#ifdef DEBUG
			assert(nOffset < strData.length() - 5);	// Not enough room for hex escape
#endif
			if (strData[nOffset + 2] >= '0'
			    && strData[nOffset + 2] <= '9') {
			    nChar = 16 * (strData[nOffset + 2] - '0');
			} else if (strData[nOffset + 2] >= 'a'
				   && strData[nOffset + 2] <= 'f') {
			    nChar = 16 * (strData[nOffset + 2] - 'a' + 10);
			} else if (strData[nOffset + 2] >= 'A'
				   && strData[nOffset + 2] <= 'F') {
			    nChar = 16 * (strData[nOffset + 2] - 'A' + 10);
			}
#ifdef DEBUG
			else {
			    assert(false);	// Invalid hex digit
			}
#endif

			if (strData[nOffset + 3] >= '0'
			    && strData[nOffset + 3] <= '9') {
			    nChar += strData[nOffset + 3] - '0';
			} else if (strData[nOffset + 3] >= 'a'
				   && strData[nOffset + 3] <= 'f') {
			    nChar += strData[nOffset + 3] - 'a' + 10;
			} else if (strData[nOffset + 3] >= 'A'
				   && strData[nOffset + 3] <= 'F') {
			    nChar += strData[nOffset + 3] - 'A' + 10;
			}
#ifdef DEBUG
			else {
			    assert(false);	// Invalid hex digit
			}
#endif

			strData2 += nChar;
			nOffset += 2;	// Fix for 4 digit excape
			break;
		    }

		    // Fix for the escape length
		    nOffset += 1;
		} else {
		    // Normal character
		    strData2 += strData[nOffset];
		}

		// Go to the next character
		nOffset += 1;
	    }
	}
#ifdef DEBUG
	else {
	    assert(false);	// Incorrect string on import
	}
#endif

	// Move this string into the column
	SetValue(strData2.c_str());
	break;

    case DataTypeInt16:
    case DataTypeInt32:
	// Move the numeric value into the column
	SetStringValue(strData.c_str());
    }
}


//--------------------------------------------------------------//
// Output this column                                           //
//--------------------------------------------------------------//
void
NxDbColumn::Output(unsigned char *ucPtr)
{
    switch (m_ucType) {
    case DataTypeChar:		// Character string
	if (m_Union.m_pszString != NULL) {
	    strcpy((char *) ucPtr, m_Union.m_pszString);
	} else {
	    *ucPtr = '\0';
	}
	break;

    case DataTypeInt16:
	put16((char *) ucPtr, m_Union.m_nInt);
	break;

    case DataTypeInt32:
	put32((char *) ucPtr, m_Union.m_nInt);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown data type
#endif
	;
    }
}


//--------------------------------------------------------------//
// Set the initial value from a string.                         //
//--------------------------------------------------------------//
void
NxDbColumn::SetStringValue(const char *pszValue)
{
    switch (m_ucType) {
    case DataTypeChar:		// character string
#ifdef DEBUG
	// Cannot exceed the maximum length
	assert(strlen(pszValue) <= m_nMaxLength);
#endif
	// Free the old value
	delete[]m_Union.m_pszString;

	// Copy the new one
	if (pszValue != NULL) {
	    m_Union.m_pszString = new char[strlen(pszValue) + 1];
	    strcpy(m_Union.m_pszString, pszValue);
	} else {
	    m_Union.m_pszString = NULL;
	}
	break;

    case DataTypeInt16:	// Short integer
	{
	    int nValue;

	    // Fix the value for discrepencies between signed and unsigned shorts
	    nValue = atoi(pszValue);	// No bad character checking
	    if (nValue > 0x7fff && nValue < 0x10000) {
		nValue -= 0x10000;
	    }
#ifdef DEBUG
	    assert(nValue >= SHRT_MIN && nValue <= SHRT_MAX);
#endif

	    m_Union.m_nInt = nValue;
	}
	break;

    case DataTypeInt32:	// Long integer
	m_Union.m_nInt = atoi(pszValue);	// No bad character checking
	break;

    default:			// Unknown type
#ifdef DEBUG
	assert(false);		// Unknown data type
#endif
	;
    }
}


//--------------------------------------------------------------//
// Reset the type of the column                                 //
//--------------------------------------------------------------//
void
NxDbColumn::SetType(int nType, int nMaxLength)
{
    // Free the old string if needed
    if (m_ucType == DataTypeChar) {
	delete[]m_Union.m_pszString;
    }

    m_ucType = nType;
    m_nMaxLength = nMaxLength;
    switch (m_ucType) {
    case DataTypeChar:		// String
	m_Union.m_pszString = NULL;
	break;

    default:			// Integer types
	m_Union.m_nInt = 0;
    }
}


//--------------------------------------------------------------//
// Set to a string value.                                       //
//--------------------------------------------------------------//
bool
NxDbColumn::SetValue(const char *pszValue)
{
    bool bReturn;

    /* FIXME:  Major hack alert - this just gets around idiocricy */

    if (m_ucType == 'i' || m_ucType == 'l') {
	int val = atoi(pszValue);
	return SetValue(val);
    }
    // Are the old and new strings equal

    if (m_Union.m_pszString == NULL) {
	bReturn = (pszValue != NULL);
    } else {
	if (pszValue != NULL) {
	    bReturn = (strcmp(m_Union.m_pszString, pszValue) != 0);
	} else {
	    bReturn = true;
	}
    }

    // Change if the values are different
    if (bReturn == true) {
	// Free the old value
	delete[]m_Union.m_pszString;

	// Copy the new one
	if (pszValue != NULL) {
	    m_Union.m_pszString = new char[strlen(pszValue) + 1];
	    strcpy(m_Union.m_pszString, pszValue);
	} else {
	    m_Union.m_pszString = NULL;
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Set to an integer value                                      //
//--------------------------------------------------------------//
bool
NxDbColumn::SetValue(int nValue)
{
    bool bReturn;


#ifdef DEBUG
    // This must be an integer column
    assert(m_ucType == 'i' || m_ucType == 'l');

    // This must be in range for a 16-bit integer
    if (m_ucType == 'i') {
	assert(nValue >= SHRT_MIN && nValue <= SHRT_MAX);
    }
#endif

    bReturn = (m_Union.m_nInt != nValue);
    m_Union.m_nInt = nValue;
    return (bReturn);
}


//--------------------------------------------------------------//
// Set to a string value                                        //
//--------------------------------------------------------------//
bool
NxDbColumn::SetValue(const string & strValue)
{
    bool bReturn;

#ifdef DEBUG
    // This must be a character column
    assert(m_ucType == 'c');
    assert(strValue.length() < m_nMaxLength);
#endif

    // Are the old and new strings different
    if (m_Union.m_pszString == NULL) {
	bReturn = true;
    } else {
	bReturn = (strValue != m_Union.m_pszString);
    }

    // Change the string if needed
    if (bReturn == true) {
	// Free the old value
	delete[]m_Union.m_pszString;

	// Copy the new one
	m_Union.m_pszString = new char[strValue.length() + 1];
	strcpy(m_Union.m_pszString, strValue.c_str());
    }
    return (bReturn);
}

--- NEW FILE: SchedulerCategoryDB.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler Category database definition fields.               //
//--------------------------------------------------------------//
#include "SchedulerCategoryDB.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Pointer to the only one of these objects.                    //
//--------------------------------------------------------------//
SchedulerCategoryDB *
    SchedulerCategoryDB::m_pThis =
    NULL;


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
SchedulerCategoryDB::SchedulerCategoryDB()
:  CategoryDB("sched_category", 10)
{
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
SchedulerCategoryDB::~SchedulerCategoryDB()
{
    m_pThis = NULL;
}


//--------------------------------------------------------------//
// Get a pointer to an open data base.                          //
//--------------------------------------------------------------//
SchedulerCategoryDB *
SchedulerCategoryDB::GetSchedulerCategoryDB()
{
    if (m_pThis == NULL) {
	m_pThis = new SchedulerCategoryDB;
    }
    return (m_pThis);
}

--- NEW FILE: ToDoListCategoryDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// ToDo List Category database class.                           //
//--------------------------------------------------------------//
#ifndef TODOLISTCATEGORYDB_H_

#define TODOLISTCATEGORYDB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "CategoryDB.h"
class ToDoListCategoryDB:public CategoryDB
{
  public:ToDoListCategoryDB();
    // Constructor
    ~ToDoListCategoryDB();	// Destructor
    static ToDoListCategoryDB *GetToDoListCategoryDB();	// Retrieve the static pointer
  private:static ToDoListCategoryDB *m_pThis;
    // One and only to do list category object
};


#endif /*  */

--- NEW FILE: ScheduleContainer.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Schedule Container widget                                    //
//--------------------------------------------------------------//
#include "config.h"
#include <cstdio>
#include <FL/fl_draw.H>
#include "FLTKUtil.h"
#include "Options.h"
#include "ScheduleContainer.h"
#include "ScheduleDay.h"
#include "Scheduler.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
ScheduleContainer::ScheduleContainer(int nX,
				     int nY,
				     int nWidth, int nHeight, int nDayCount)
    :
Fl_Scroll(nX, nY, nWidth, nHeight)
{
    char szLabel[24];
    int i;
    time_t nDate = NormalizeDate(time(NULL));

    // Set that nothing is selected
    m_nSelectedRow = -1;

    // Get the size of an hour in the display, same calculation as in GetHourWidth
    m_nHourHeight = 3 * labelsize();
    sprintf(szLabel, "  12:00%s ", _("pm"));
    fl_measure(szLabel, m_nHourWidth, m_nHourHeight);
    m_nHourHeight = ((3 * m_nHourHeight + 1) & (-2));	// Make this an even number for half hours

    // Set a vertical scrollbar only]
    type(Fl_Scroll::VERTICAL);

    // Create the group for the hourly labels
    m_pHour = new ScheduleHours(nX, nY, m_nHourWidth, m_nHourHeight);

    // Create a group for resizing
    m_pResizeGroup = new Fl_Group(nX + m_nHourWidth,
				  nY,
				  nWidth - m_nHourWidth - scrollbar.w(),
				  24 * m_nHourHeight);


    // Create the days for the schedule display
    m_nDayCount = nDayCount;
    m_ppDay = new PSCHEDULEDAY[m_nDayCount];
    for (i = 0; i < nDayCount; ++i) {
	m_ppDay[i] =
	    new ScheduleDay(nX + m_nHourWidth +
			    i * ((nWidth - m_nHourWidth - scrollbar.w()) /
				 nDayCount), nY,
			    i ==
			    nDayCount - 1 ? nWidth - m_nHourWidth -
			    scrollbar.w() - (nDayCount -
					     1) * ((nWidth - m_nHourWidth -
						    scrollbar.w()) /
						   nDayCount)
			    : (nWidth - m_nHourWidth -
			       scrollbar.w()) / nDayCount, 24 * m_nHourHeight,
			    m_nHourHeight, nDate);
	nDate = AddDays(nDate, 1);
    }

    // End the resizing group
    m_pResizeGroup->end();
    resizable(m_pResizeGroup);

    // End this widget
    end();

    // Set up a frame
    box(FL_ENGRAVED_FRAME);

    // Position at the correct start time
    position(0, Options::GetDayBegins() * m_nHourHeight);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
ScheduleContainer::~ScheduleContainer()
{
    delete[]m_ppDay;
}


//--------------------------------------------------------------//
// Process a request to delete an appointment.  This            //
// ScheduleContainer is within an anonymous Fl_Group within     //
// either a SchedulerDaily or SchedulerWeekly page.  Either of  //
// those is within a Fl_Tabs within a Scheduler object.  This   //
// method notifies the Scheduler object of the request.         //
//--------------------------------------------------------------//
void
ScheduleContainer::Delete(int nRow, time_t nDate)
{
    ((Scheduler *) (parent()->parent()->parent()->parent()))->Delete(nRow,
								     nDate);
}


//--------------------------------------------------------------//
// Process a request to edit an appointment.  This              //
// ScheduleContainer is within an anonymous Fl_Group within     //
// either a SchedulerDaily or SchedulerWeekly page.  Either of  //
// those is within a Fl_Tabs within a Scheduler object.  This   //
// method notifies the Scheduler object of the request.         //
//--------------------------------------------------------------//
void
ScheduleContainer::Edit(int nRow, time_t nDate)
{
    ((Scheduler *) (parent()->parent()->parent()->parent()))->Edit(nRow,
								   nDate);
}


//--------------------------------------------------------------//
// Process a request to add a new appointment.  This            //
// ScheduleContainer is within an anonymous Fl_Group within     //
// either a SchedulerDaily or SchedulerWeekly page.  Either of  //
// those is within a Fl_Tabs within a Scheduler object.  This   //
// method notifies the Scheduler object of the request.         //
//--------------------------------------------------------------//
void
ScheduleContainer::EditNew(time_t nDate)
{
    // Go fire up the new appointment dialog
    ((Scheduler *) (parent()->parent()->parent()->parent()))->EditNew(nDate);
}


//--------------------------------------------------------------//
// Refresh all ScheduleDay objects in this container            //
//--------------------------------------------------------------//
void
ScheduleContainer::Refresh(time_t nDate)
{
    int i;

    // Normalize the date
    m_nDate = nDate =::NormalizeDate(nDate);

    // Tell each child of the refresh
    for (i = 0; i < m_nDayCount; ++i) {
	m_ppDay[i]->Refresh(nDate);
	nDate = AddDays(nDate, 1);
    }

    // Set that nothing is selected
    m_nSelectedRow = -1;
}


//--------------------------------------------------------------//
// Override the Fl_Scroll resize processing to cause the days   //
// to widen on a resize operation.                              //
//--------------------------------------------------------------//
void
ScheduleContainer::resize(int nX, int nY, int nWidth, int nHeight)
{
    // Invoke the base class
    Fl_Scroll::resize(nX, nY, nWidth, nHeight);

    // Fix the x-position and width of the resizabel group in the container
    // since Fl_Scroll only moves children and does not resize them
    m_pResizeGroup->resize(nX + m_nHourWidth,
			   m_pResizeGroup->y(),
			   nWidth - m_nHourWidth - scrollbar.w(),
			   m_pResizeGroup->h());

    // Now refresh the ScheduleDay groups to get the events to be the correct size
    Refresh(m_nDate);
}

--- NEW FILE: FindList.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Find Dialog List of found items.                             //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/Fl_Menu_Item.H>
#include "FindDlg.h"
#include "FindList.h"
#include "FLTKUtil.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
FindList::FindList(int nX, int nY, int nWidth, int nHeight)
    :
TableBase(nX, nY, nWidth, nHeight)
{
    bool bIconColumns[2] = { false, false };

    PostConstructor(0, 2, bIconColumns);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
FindList::~FindList()
{
}


//--------------------------------------------------------------//
// Calculate column widths after a resize.  The TableBase class //
// will already have set the m_nColWidth array to zeroes.       //
//--------------------------------------------------------------//
void
FindList::CalculateColumnWidths(int nWidth)
{
    m_nColWidth[0] = 20 * nWidth / 100;	// 20% of it
    m_nColWidth[1] = nWidth - m_nColWidth[0];	// The rest
}


//--------------------------------------------------------------//
// Process a double click over a row, Go To that item.          //
//--------------------------------------------------------------//
void
FindList::DoubleClick(int nRow, int nCol)
{
    ((FindDlg *) parent())->Notify(FIND_ITEM_REQUESTED, nRow);
}


//--------------------------------------------------------------//
// Get the number of rows to be displayed                       //
//--------------------------------------------------------------//
int
FindList::GetRowCount()
{
    return (((FindDlg *) parent())->GetFindRows());
}


//--------------------------------------------------------------//
// Get the string value of a column.                            //
//--------------------------------------------------------------//
string
FindList::GetStringValue(int nRow, int nCol)
{
    string strReturn;

    switch (nCol) {
    case 0:			// First column
	switch (((FindDlg *) parent())->GetFindType(nRow)) {
	case ADDRESS_BOOK_GOTO:	// Address Book item
	    strReturn = _("Address");
	    break;

	case NOTES_GOTO:	// Notes item
	    strReturn = _("Note");
	    break;

	case SCHEDULER_GOTO:	// Scheduler/appointment item
	    strReturn = _("Appointment");
	    break;

	case TODO_LIST_GOTO:	// ToDo List item
	    strReturn = _("ToDo List");
	    break;

	default:
#ifdef DEBUG
	    assert(false);	// Unknown type
#endif
	    ;
	}
	break;

    case 1:			// Second columnKey of the item
	strReturn = ((FindDlg *) parent())->GetFindKey(nRow);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Should not get here for some other column
#endif
	;
    }

    return (strReturn);
}


//--------------------------------------------------------------//
// Process a right mouse click anywhere                         //
//--------------------------------------------------------------//
void
FindList::RightClick(int nRow, int nCol)
{
    static const Fl_Menu_Item menuPopup[] = {
	{N_("Go To this Item")},
	{NULL},
    };
    int nSelection;

    // Display the popup menu
    nSelection = DoPopupMenu(menuPopup, Fl::event_x(), Fl::event_y());

    if (nSelection >= 0) {
	// Only one selection
	((FindDlg *) parent())->Notify(FIND_ITEM_REQUESTED, nRow);
    }
}

--- NEW FILE: NxDbAccess.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class to access an NxDb database for desktop applications.   //
// This keeps the contents of the database (file) in memory and //
// will write out changes only to disk as needed.               //
//--------------------------------------------------------------//
#ifndef NXDBACCESS_H_

#define NXDBACCESS_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <cassert>
#include <set>
#include <string>
#include <vector>
#include <nxdb.h>
#include "NxDbRow.h"
using namespace std;
typedef bool(*FNCUSTOMCOMPARE) (NxDbRow * pRow1,	// Custom comparison routine for sorting
				NxDbRow * pRow2);
class NxDbAccess
{
  public:NxDbAccess(const char *pszFileName,
	       // Constructor, opens a database
	       /*const */ fildes * pDescription,
	       /*const */ field * pField);
      virtual ~ NxDbAccess();	// Destructor, closes the database
    static void CloseAll();	// Close all open data bases
    static void RefreshAll();	// Close and reopen all data bases
    virtual void Delete(int nRow);	// Delete a row from the data base
    void Dump(const char *pszFileName);	// Dump the database contents to a file
    static void DumpAll();	// Dump all open databases
    virtual inline void Export(int nRow,	// Convert a row to a set of strings
			       vector < string > &vExportString)
    {

#ifdef DEBUG
	assert(nRow >= 0 && nRow < NumRecs());

#endif				/*  */
	m_vpRow[nRow]->Export(vExportString);
    }
    int FindFirst(int nCol,	// Find the first row with a column like pszValue
		  const char *pszValue);
    inline int FindPhysicalRecord(int nRecordNumber)	// Find a row by physical record number
    {
	return (FindPhysicalRecord(nRecordNumber, m_vpRow));
    }
    static int FindPhysicalRecord(int nRecordNumber,	// Get the physical record number for a local row
				  ROW_VECTOR vpRow);
    int FindRealRow(int nRow,	// Find the real row number for a local row
		    ROW_VECTOR & vpRow);
    int FindRow(int nCol,	// Find a row by key value
		int nValue);
    int FindRow(int nCol,	// Find a row by key value
		const char *pszValue);
    int GetColumnSize(int nCol);	// Get the maximum size of a column
    inline int GetIntValue(int nRow, int nCol) const	// Get the value of this column as an integer
    {

#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);

#endif				/*  */
	return (m_vpRow[nRow]->GetIntValue(nCol));
    }

    inline int GetFlags(int nRow)
    {
#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);
#endif

	return m_vpRow[nRow]->GetFlags();
    }

    inline void SetFlags(int nRow, int flags)
    {
#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);
#endif

	m_vpRow[nRow]->SetFlags(flags);
    }

    int GetLocalRow(int nRow,	// Get the local row number for a real row
		    ROW_VECTOR & vpRow);
    inline int GetRecordNumber(int nRow,	// Get the physical record number for this row
			       ROW_VECTOR & vpRow)
    {

#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);

#endif /*  */
	return (vpRow[nRow]->GetRecordNumber());
    }
    inline int GetRecordNumber(int nRow)	// Get the physical record number for this row
    {

#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);

#endif /*  */
	return (m_vpRow[nRow]->GetRecordNumber());
    }
    ROW_VECTOR GetRows();	// Get an array of row pointers
    inline string GetStringValue(int nRow, int nCol) const	// Get the value of this column as a string
    {

#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);

#endif				/*  */
	return (m_vpRow[nRow]->GetStringValue(nCol));
    }
    virtual int Import(const vector < string > &strData);	// Import a delimited string as a new row

    virtual int Insert();	// Insert a new row into the data base, derived classes must set any key value as needed
    inline bool IsDeleted(int nRow)	// Determine if this is a deleted row
    {

#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);

#endif /*  */
	return (m_vpRow[nRow]->IsDeleted());
    }
    static inline bool IsDeleted(int nRow,	// Determine if a local copy of a row is deleted
				 ROW_VECTOR & vpRow)
    {

#ifdef DEBUG
	assert(nRow < (int) vpRow.size() && nRow >= 0);

#endif /*  */
	return (vpRow[nRow]->IsDeleted());
    }
    inline int NumRecs()	// Get the row count
    {
	return (m_pNxDb->NumRecs(m_strDbName));
    }
    int NumRecsByKey(int nCol,	// Get the row count for rows with a particular value
		     const char *pszValue);
    int NumRecsByKey(int nCol,	// Get the row count for rows with a particular value
		     int nValue);
    int NumUndeletedRecs();	// Get the number of undeleted rows
    bool Save();		// Write all changed rows to disk
    void UpdateFlags();         // Update the flags of the saved objects

    static void SaveCmdLine(int argc,	// Save pointers to the command line arguments
			    char **argv);
    bool Search(int nRow,	// Search all character strings in a row for a match to another string
		const char *pszString, bool bMatchWholeWord, bool bMatchCase);
    inline bool SetColumn(int nRow,	// Set the value of a column
			  int nCol, const char *pszValue)
    {

#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);

#endif /*  */
	return (m_vpRow[nRow]->SetColumn(nCol, pszValue));
    }
    inline bool SetColumn(int nRow,	// Set the value of a column
			  int nCol, int nValue)
    {

#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);

#endif /*  */
	return (m_vpRow[nRow]->SetColumn(nCol, nValue));
    }
    void SetHighKey(int nRow,	// Set a unique key value for a column
		    int nKeyColumn);
    void SetHighStringKey(int nRow,	// Set a unique key value for a character string column
			  int nKeyColumn);
    void Sort(FNCUSTOMCOMPARE pfnCompareRoutine);	// Sort the rows in memory with a custom comparison routine
    void Sort(FNCUSTOMCOMPARE pfnCompareRoutine,	// Sort a local copy of the rows with a custom comparison routine
	      ROW_VECTOR & vRow);
    void Sort(int nCol);	// Sort the rows in memory
    bool TestDuplicate(const char *pszString,	// Test for a duplicate string in the database
		       int nExistingKey, int nStringColumn, int nKeyColumn);
    void Close();		// Close this data base (used in some derived constructors)
    void Open();

    void GetSchema(vector < char >&, vector < int >&);

  protected:bool m_bClosed;	// True if an early close was performed in a derived constructor
    inline void SetStringValue(int nRow,	// Set the value of a column
			       int nCol, const char *pszValue)
    {

#ifdef DEBUG
	assert(nRow < (int) m_vpRow.size() && nRow >= 0);

#endif /*  */
	m_vpRow[nRow]->SetStringValue(nCol, pszValue);
    }
  private:char *m_pszFileName;
    fildes *m_pDescription;
    field *m_pField;
    bool m_bOpen;		// Is the database currently open
    static char **m_ppszArgv;	// Command line arguments
    static int m_nArgc;		// Command line arguments
    static int m_nSortColumn;	// Kludge - the column currently being sorted on
    int m_nSortOrder;		// Last column sorted on
    static set < NxDbAccess * >m_setOpenDB;	// List of pointers to currently open data bases
    static NxDb *m_pNxDb;	// The database object, kept open to prevent file sharing
    ROW_VECTOR m_vpRow;		// Rows for this data base
    string m_strDbName;		// Name of the data base for NxDb
    static bool(*m_pfnCompareRoutine) (NxDbRow *, NxDbRow *);	// Kludge - Custom comparison routine currently in use
    static bool CompareCustom(NxDbRow * pRow1,	// Compare rows using a custom comparison routine
			      NxDbRow * pRow2);
    static int CompareDeleted(NxDbRow * pRow1,	// Compare the deleted status of two rows
			      NxDbRow * pRow2);
    static bool CompareInteger(NxDbRow * pRow1,	// Compare rows by contents of an integer column
			       NxDbRow * pRow2);
    static bool ComparePhysicalRecord(NxDbRow * pRow1,	// Compare rows by physical record number
				      NxDbRow * pRow2);
    static bool CompareString(NxDbRow * pRow1,	// Compare rows by contents of a string column
			      NxDbRow * pRow2);
    static void DoSort(FNCUSTOMCOMPARE pfnCompareRoutine,	// Workaround for Visual C/STL problem
		       ROW_VECTOR & vpRow);
    void ReadAll();		// Read all rows from the database into memory
    bool SearchString(const char *pszHaystack,	// Search for one string in another
		      const char *pszNeedle, bool bMatchWholeWord,
		      bool bMatchCase);
};


#endif /*  */

--- NEW FILE: NxDbAccess.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
[...1160 lines suppressed...]
	    }
	}
    }
    return (bReturn);
}

void
NxDbAccess::GetSchema(vector < char >&col_type, vector < int >&col_size)
{
    int idx = 0;

    field *pField = m_pNxDb->GetField(m_strDbName);
    field *p_field;

    for (p_field = pField; p_field->type != 0; p_field = &(pField[++idx])) {

      col_size.push_back(p_field->size);
      col_type.push_back(p_field->type);
    }
}

--- NEW FILE: ImageBox.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for a box with an image and which tracks mouse         //
// movements and allows left mouse clicks on the image.         //
//--------------------------------------------------------------//
#ifndef IMAGEBOX_H_

#define IMAGEBOX_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <string>
#include <FL/Fl_Group.H>
#include <FL/Fl_Pixmap.H>
#include "Messages.h"
using namespace std;
class ImageBox:public Fl_Group
{
  public:ImageBox(int nX,	// Constructor
	     int nY, int nWidth, int nHeight, Fl_Pixmap * pPixmap,
	     PixilDTMessage nMessage, const char *pszPrompt);
     ~ImageBox();		// Destructor
    int Message(PixilDTMessage nMessage,	// Processing from the parent's callback function
		int nInfo);
  protected:void draw();	// Draw this widget
    int handle(int nEvent);	// Handle events in this widget
  private:  bool m_bMouseDown;
    // Is the mouse down for this widget
    bool m_bMouseIn;		// Is the mouse in this widget
    Fl_Color m_nDownColor;	// The "down" background color
    Fl_Color m_nNormalColor;	// The original background color
    Fl_Pixmap *m_pPixmap;	// Pointer to the image
    enum PixilDTMessage m_nMessage;	// Message to issue when selected
      std::string m_strPrompt;	// Prompt for the image
    void PopDown();		// Pop the image down
    void PopUp();		// Pop the image up
};


#endif /*  */

--- NEW FILE: CategoryDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Base class for all Category database classes.                //
//--------------------------------------------------------------//
#ifndef CATEGORYDB_H_

#define CATEGORYDB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Menu_Item.H>
#include "NxDbAccess.h"

// Field References
#define CATID 0
#define CAT   1
class CategoryDB:public NxDbAccess
{
  public:CategoryDB(const char *pszFileName,
	       // Constructor
	       int nCategoryLength);
     ~CategoryDB();		// Destructor
    inline string GetCategory(int nRow) const	// Get the category string
    {
	return (GetStringValue(nRow, CAT));
    }
    Fl_Menu_Item *GetCategoryMenu(bool bIncludeAll);	// Create a menu for a category choice widget
    Fl_Menu_Item *GetCategoryMenuWithFont(bool bIncludeAll,	// Create a menu for a category choice widget
					  Fl_Font nFont,
					  unsigned char nFontSize);
    inline int GetCategoryID(int nRow) const	// Get the recno column
    {
	return (GetIntValue(nRow, CATID));
    }
    int Insert(int nID);	// Insert a row and set its key id
    inline void SetCategory(int nRow, const char *pszCategory)	// Set the category string
    {
	SetColumn(nRow, CAT, pszCategory);
    }
    bool TestDuplicate(const char *pszString,	// Test a name for duplicates
		       void *pData);
  private:static bool m_bFieldInUse[4];
    // Indicators for static field definitions bing in use
    static const char *m_pszDefaultCategory[3];	// Default categories for database initialization
    static field *m_pStaticField[4];	// Field definitions used during construction
    static fildes *m_pStaticFildes[4];	// Data base definition used during custruction
    int m_nIndex;		// Index to the field definitions used for this data base
    static int m_nLastIndexUsed;	// Used during construction process
    void Init();		// Initialize the data base at open
    static field *CreateFields(int nCategoryLength);	// Create the database fields definition
};


#endif /*  */

--- NEW FILE: NoteDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Notes database class.                                        //
//--------------------------------------------------------------//
#ifndef NOTEDB_H_

#define NOTEDB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <vector>
#include "Note.h"
#include "NxDbAccess.h"
using namespace std;

// Field References
#define NOTE_INDEX      0
#define NOTE_CAT        1
#define NOTE_FILE       2
#define NOTE_DESC       3
#define NOTE_ARCH       4
#define NOTE_NUM_FIELDS 5

#define NOTE_TITLE_LEN 50
#define NOTE_FILE_LEN 100

#define NOTE_NOTES_PREFIX "not_"
class NoteDB:public NxDbAccess
{
  public:NoteDB();		// Constructor
    ~NoteDB();			// Destructor
    void Delete(int nRow);	// Delete the note file for this note as well
    void Export(int nRow,	// Export to a set of strings
		vector < string > &vExportString);
    inline int GetArchiveFlag(int nRow) const	// Get the archive flag
    {
	return (GetIntValue(nRow, NOTE_ARCH));
    }
    inline int GetCategory(int nRow) const	// Get the category
    {
	return (GetIntValue(nRow, NOTE_CAT));
    }
    string GetCategoryName(int nRow) const;	// Get the category name
    inline string GetFile(int nRow) const	// Get the note file
    {
	return (GetStringValue(nRow, NOTE_FILE));
    }
    inline int GetIndex(int nRow) const	// Get the index
    {
	return (GetIntValue(nRow, NOTE_INDEX));
    }
    static NoteDB *GetNoteDB();	// Get the singleton pointer
    Note *GetNote(int nRow) const;	// Get the actual note
    inline string GetTitle(int nRow) const	// Get the title
    {
	return (GetStringValue(nRow, NOTE_DESC));
    }
    int Import(const vector < string > &vExportString);	// Import a delimited string
    int Insert(int nCategory);	// Insert a row and set its key value
    inline void SetArchiveFlag(int nRow, int nArchiveFlag)	// Set the archive flag
    {
	SetColumn(nRow, NOTE_ARCH, nArchiveFlag);
    }
    inline void SetCategory(int nRow, int nCategory)	// Set the category
    {
	SetColumn(nRow, NOTE_CAT, nCategory);
    }
    inline void SetFile(int nRow, const char *pszFile)	// Set the note file
    {
	SetColumn(nRow, NOTE_FILE, pszFile);
    }
    inline void SetIndex(int nRow, int nIndex)	// Set the index
    {
	SetColumn(nRow, NOTE_INDEX, nIndex);
    }
    void SetNote(int nRow,	// Set the note
		 Note * pNote);
    inline void SetTitle(int nRow, const char *pszTitle)	// Set the title
    {
	SetColumn(nRow, NOTE_DESC, pszTitle);
    }
  private:static NoteDB *m_pThis;
    // One and only object
};


#endif /*  */

--- NEW FILE: IniDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Dialog for a missing INI file or a new user.                 //
//--------------------------------------------------------------//
#include "config.h"
#ifndef WIN32
#include <unistd.h>
#else
#include <direct.h>
#endif
#include <FL/filename.H>
#include <FL/fl_message.H>
#include <FL/Fl_Return_Button.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "IniDlg.h"
#include "InputBox.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#define PROMPT_WIDTH 140
#define DLG_HEIGHT   (4*DLG_BORDER+4*DLG_BUTTON_HEIGHT)
#define DLG_WIDTH    (2*DLG_BORDER+PROMPT_WIDTH+400+DLG_BUTTON_WIDTH)


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
IniDlg::IniDlg()
:  Fl_Window(DLG_WIDTH, DLG_HEIGHT, _("New User Settings"))
{
    Fl_Box *pBox;

    // Create the widgets
    pBox = new Fl_Box(DLG_BORDER,
		      DLG_BORDER,
		      w() - 2 * DLG_BORDER, 2 * DLG_BUTTON_HEIGHT);
    pBox->align(Fl_Align(FL_ALIGN_INSIDE + FL_ALIGN_WRAP));
    pBox->
	label(_
	      ("You are a new user.  Please enter the directory where you would to have the Pixil Desktop files stored:"));
    m_pDataDir =
	new Fl_Input(PROMPT_WIDTH, 2 * DLG_BORDER + 2 * DLG_BUTTON_HEIGHT,
		     w() - 2 * DLG_BORDER - DLG_BUTTON_WIDTH - PROMPT_WIDTH,
		     DLG_INPUT_HEIGHT, _("Data Directory:"));
    m_pDataDir->maximum_size(256);
    m_pBrowseButton = new Fl_Button(w() - DLG_BORDER - DLG_BUTTON_WIDTH,
				    2 * DLG_BORDER + 2 * DLG_BUTTON_HEIGHT,
				    DLG_BUTTON_WIDTH,
				    DLG_BUTTON_HEIGHT, _("&Browse"));
    m_pBrowseButton->callback(OnBrowseButton);

    // Create the buttons
    m_pOKButton =
	new Fl_Return_Button(w() - 3 * DLG_BORDER - 3 * DLG_BUTTON_WIDTH,
			     h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
			     DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton =
	new Fl_Button(w() - 2 * DLG_BORDER - 2 * DLG_BUTTON_WIDTH,
		      h() - DLG_BUTTON_HEIGHT - DLG_BORDER, DLG_BUTTON_WIDTH,
		      DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - DLG_BORDER - DLG_BUTTON_WIDTH,
				  h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
				  DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);

    // Finish the dialog
    end();

    // The DoModal method will show this dialog
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
IniDlg::~IniDlg()
{
}


//--------------------------------------------------------------//
// Run the modal dialog.                                        //
//--------------------------------------------------------------//
int
IniDlg::DoModal()
{
    bool bGood;
    int nResult;

    // Keep doing the dialog until a good directory is entered
    // or the cancel button is pressed
    do {
	nResult =::DoModal(this, m_pOKButton, m_pCancelButton);
	if (nResult == 0) {
	    // Cancel button
	    break;
	}
	bGood = ValidateDirectory(m_pDataDir->value(), m_strPath);
    } while (bGood == false);

    return (bGood);
}


//--------------------------------------------------------------//
// Browse button was clicked (static callback).                 //
//--------------------------------------------------------------//
void
IniDlg::OnBrowseButton(Fl_Widget * pWidget, void *pUserData)
{
    InputBox *pInputBox;
    IniDlg *pThis = (IniDlg *) (pWidget->parent());

    // Get the directory name
    pInputBox = new InputBox(_("Data Directory"),
			     pThis,
			     pThis->m_pDataDir->value(),
			     256,
			     HELP_NEW_USER,
			     Validate,
			     pThis,
			     NULL, _("Please enter the data directory:"));
    if (pInputBox->GetEntry().length() > 0) {
	pThis->m_pDataDir->value(pInputBox->GetEntry().c_str());
    }
    delete pInputBox;
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
IniDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_NEW_USER);
}


//--------------------------------------------------------------//
// Validate a new data directory (static callback).             //
//--------------------------------------------------------------//
bool
IniDlg::Validate(const char *pszString, Fl_Widget * pThis, void *pUserData)
{
    bool bNotBlank = false;
    int i;

    // The directory cannot start or end with a blank
    if (!isspace(pszString[0]) && !isspace(pszString[strlen(pszString) - 1])) {
	// The directory cannot be completely blank
	for (i = 0; pszString[i] != '\0'; ++i) {
	    if (!isspace(pszString[i])) {
		bNotBlank = true;
		break;
	    }
	}
    }
    return (bNotBlank);
}


//--------------------------------------------------------------//
// Validate an entered directory.                               //
//--------------------------------------------------------------//
bool
IniDlg::ValidateDirectory(const char *pszDirectory, string & strPath)
{
    bool bCreated;
#ifndef WIN32
    static const char cSlash = '/';
#else
    static const char cSlash = '\\';
#endif
    char szDirectory[1024];
    char szPath[1024];
    bool bReturn = false;
    FILE *file;
#ifdef WIN32
    int nDrive;
    int nOldDrive;
#endif
    int nResult;
#ifndef WIN32
    string strCommand;
#endif
    string strDir;
    string strFile;
    string strFile2;
    unsigned int nPos;

    // Save the current directory
    getcwd(szDirectory, sizeof(szDirectory));

#ifdef WIN32
    // Save the current drive letter
    nOldDrive = _getdrive();
    nDrive = nOldDrive;
#endif

    // Is there a file name
    if (strlen(pszDirectory) > 0) {
	// Is this a directory
	if (filename_isdir(pszDirectory)) {
	    // Does it already contain a data base
	    strFile = pszDirectory;
	    if (strFile[strFile.length() - 1] == cSlash
		&& strFile.length() > 1) {
		strFile = strFile.substr(0, strFile.length() - 1);
	    }
	    strFile += cSlash;
	    strFile += "PixilDT.ini";
	    file = fopen(strFile.c_str(), "r");
	    if (file != NULL) {
		// A database already exists in this directory,
		// ask the user whether to use it or not
		fclose(file);
		nResult =
		    fl_ask(_
			   ("A database already exists in this directory, use the data in this existing data base?"));
		bReturn = (nResult == 1);
	    } else {
		bReturn = true;
	    }
	} else			// Not an existing directory
	{
	    // Is this an existing file ?
	    file = fopen(pszDirectory, "r");
	    if (file != NULL) {
		// This is a file and cannot be used
		fclose(file);
		fl_message(_
			   ("This name already exists as a file so it cannot be used as the target directory"));
	    } else		// Not an existing file
	    {
		// Ask if it should be created
		nResult =
		    fl_ask(_
			   ("This directory does not exist yet, should it be created?"));
		bReturn = (nResult == 1);

		// Now create the directory if needed
		if (bReturn == true) {
		    strFile = pszDirectory;

#ifndef WIN32
		    if (strFile[0] != cSlash) {
			getcwd(szDirectory, sizeof(szDirectory));
			strFile2 = strFile;
			strFile = szDirectory;
			strFile += '/';
			strFile += strFile2;
		    }
#else
		    if (strFile[1] == ':'
			&& ((strFile[0] >= 'A' && strFile[0] <= 'Z')
			    || (strFile[0] >= 'a' && strFile[0] <= 'z'))) {
			if ((strFile[0] >= 'A' && strFile[0] <= 'Z')) {
			    nDrive = strFile[0] - 'A' + 1;
			} else {
			    nDrive = strFile[0] - 'a' + 1;
			}
			strFile = strFile.substr(2);
		    } else {
			nDrive = _getdrive();
		    }
		    if (strFile[0] != cSlash) {
			getcwd(szDirectory, sizeof(szDirectory));
			strFile2 = strFile;
			strFile = szDirectory;
			strFile += '\\';
			strFile += strFile2;
		    }
#endif

#ifdef WIN32
		    // Switch to the selected drive
		    _chdrive(nDrive);
#endif

		    // Go to the root directory
		    strDir = cSlash;
		    chdir(strDir.c_str());

		    // Create each directory in turn
		    bCreated = false;
		    while (strFile.length() > 0) {
			// Remove the leading slash
			strFile = strFile.substr(1);

			// Find the next slash
			nPos = strFile.find_first_of(cSlash);

			// Was one found
			if (nPos != string::npos) {
			    // Get the next directory level
			    strDir = strFile.substr(0, nPos);
			    strFile = strFile.substr(nPos);

			    // Go to this directory
			    if (chdir(strDir.c_str()) != 0) {
				// Create this directory level
#ifndef WIN32
				strCommand = "mkdir ";
				strCommand += strDir.c_str();
				if (system(strCommand.c_str()) != 0)
#else
				if (mkdir(strDir.c_str()) != 0)
#endif
				{
				    break;
				}
				chdir(strDir.c_str());
			    }
			} else {
			    // Last level of sub-directories
#ifndef WIN32
			    strCommand = "mkdir ";
			    strCommand += strFile.c_str();
			    if (system(strCommand.c_str()) != 0)
#else
			    if (mkdir(strFile.c_str()) != 0)
#endif
			    {
				break;
			    }
			    strFile = "";
			    bCreated = true;
			}
		    }

		    // Was everything created
		    if (bCreated == true) {
			bReturn = true;
		    } else {
			fl_message(_("Unable to create the directory."));
		    }
		}
	    }
	}
    }
#ifdef WIN32
    // Switch back to the original drive
    _chdrive(nOldDrive);
#endif

    // Switch back to the original directory
    chdir(szDirectory);

    // Fix up the output path if all is well
    if (bReturn == true) {
	filename_absolute(szPath, pszDirectory);

#ifndef WIN32
	// Save the final path
	strPath = szPath;
#else
	// Add the drive letter to the path if needed
	if (strFile[1] != ':'
	    || ((strFile[0] < 'A' || strFile[0] > 'Z')
		&& (strFile[0] < 'a' || strFile[0] > 'z'))) {
	    strPath = nDrive + 'A' - 1;
	    strPath += ':';
	    strPath += szPath;
	} else {
	    strPath = szPath;
	}
#endif

    }

    return (bReturn);
}

--- NEW FILE: PixilDT.dsw ---
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!

###############################################################################

Project: "NxDb"="..\NxDb\NxDb.dsp" - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
}}}

###############################################################################

Project: "PixilDT"=".\PixilDT.dsp" - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
    Begin Project Dependency
    Project_Dep_Name getopt
    End Project Dependency
    Begin Project Dependency
    Project_Dep_Name NxDb
    End Project Dependency
    Begin Project Dependency
    Project_Dep_Name flvw
    End Project Dependency
    Begin Project Dependency
    Project_Dep_Name libintl
    End Project Dependency
    Begin Project Dependency
    Project_Dep_Name libnlsut
    End Project Dependency
    Begin Project Dependency
    Project_Dep_Name fltk
    End Project Dependency
}}}

###############################################################################

Project: "fltk"="..\..\fltk-1.0.11\visualc\fltk.lib.dsp" - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
}}}

###############################################################################

Project: "flvw"="..\..\FLVW\1.0\vc6\flvw\flvw.dsp" - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
}}}

###############################################################################

Project: "getopt"="..\getopt\getopt.dsp" - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
}}}

###############################################################################

Project: "libintl"="..\gettext-0.10.38\visualc\libintl\libintl.dsp" - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
}}}

###############################################################################

Project: "libnlsut"="..\gettext-0.10.38\visualc\libnlsut\libnlsut.dsp" - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
}}}

###############################################################################

Global:

Package=<5>
{{{
}}}

Package=<3>
{{{
}}}

###############################################################################


--- NEW FILE: PixilDT.dsp ---
# Microsoft Developer Studio Project File - Name="PixilDT" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=PixilDT - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "PixilDT.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "PixilDT.mak" CFG="PixilDT - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "PixilDT - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "PixilDT - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE 

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe

!IF  "$(CFG)" == "PixilDT - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "c:\fltk-1.0.11" /I "c:\flvw\1.0" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /machine:I386
# SUBTRACT LINK32 /pdb:none

!ELSEIF  "$(CFG)" == "PixilDT - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "c:\fltk-1.0.11" /I "c:\flvw\1.0" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /debug /machine:I386 /pdbtype:sept
# SUBTRACT LINK32 /pdb:none

!ENDIF 

# Begin Target

# Name "PixilDT - Win32 Release"
# Name "PixilDT - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=.\AddressBook.cpp
# End Source File
# Begin Source File

SOURCE=.\AddressBookCategoryDB.cpp
# End Source File
# Begin Source File

SOURCE=.\AddressBookDB.cpp
# End Source File
# Begin Source File

SOURCE=.\AddressBookDetails.cpp
# End Source File
# Begin Source File

SOURCE=.\AddressBookDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\AddressBookList.cpp
# End Source File
# Begin Source File

SOURCE=.\CategoryDB.cpp
# End Source File
# Begin Source File

SOURCE=.\CategoryEditor.cpp
# End Source File
# Begin Source File

SOURCE=.\CategoryEditorList.cpp
# End Source File
# Begin Source File

SOURCE=.\CustomFieldDB.cpp
# End Source File
# Begin Source File

SOURCE=.\CustomFieldEditor.cpp
# End Source File
# Begin Source File

SOURCE=.\DatePicker.cpp
# End Source File
# Begin Source File

SOURCE=.\DatePickerDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\FindDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\FindList.cpp
# End Source File
# Begin Source File

SOURCE=.\FLTKUtil.cpp
# End Source File
# Begin Source File

SOURCE=.\ImageBox.cpp
# End Source File
# Begin Source File

SOURCE=.\Images.cpp
# End Source File
# Begin Source File

SOURCE=.\InfoDB.cpp
# End Source File
# Begin Source File

SOURCE=.\InfoGroup.cpp
# End Source File
# Begin Source File

SOURCE=.\IniDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\InputBox.cpp
# End Source File
# Begin Source File

SOURCE=.\InputNotify.cpp
# End Source File
# Begin Source File

SOURCE=.\LeftGroup.cpp
# End Source File
# Begin Source File

SOURCE=.\ListByDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\Note.cpp
# End Source File
# Begin Source File

SOURCE=.\NoteDB.cpp
# End Source File
# Begin Source File

SOURCE=.\NoteDetails.cpp
# End Source File
# Begin Source File

SOURCE=.\NoteEditor.cpp
# End Source File
# Begin Source File

SOURCE=.\NoteEditorDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\NoteList.cpp
# End Source File
# Begin Source File

SOURCE=.\Notes.cpp
# End Source File
# Begin Source File

SOURCE=.\NotesCategoryDB.cpp
# End Source File
# Begin Source File

SOURCE=.\NxDbAccess.cpp
# End Source File
# Begin Source File

SOURCE=.\NxDbColumn.cpp
# End Source File
# Begin Source File

SOURCE=.\NxDbRow.cpp
# End Source File
# Begin Source File

SOURCE=.\Options.cpp
# End Source File
# Begin Source File

SOURCE=.\OptionsDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\PixilDT.cpp
# End Source File
# Begin Source File

SOURCE=.\PixilDT.rc
# End Source File
# Begin Source File

SOURCE=.\PixilDTApp.cpp
# End Source File
# Begin Source File

SOURCE=.\PixilMainWnd.cpp
# End Source File
# Begin Source File

SOURCE=.\Printer.cpp
# End Source File
# Begin Source File

SOURCE=.\ScheduleContainer.cpp
# End Source File
# Begin Source File

SOURCE=.\ScheduleDay.cpp
# End Source File
# Begin Source File

SOURCE=.\ScheduleEvent.cpp
# End Source File
# Begin Source File

SOURCE=.\ScheduleHours.cpp
# End Source File
# Begin Source File

SOURCE=.\Scheduler.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerCategoryDB.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerChangeTypeDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerDaily.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerDB.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerMonthly.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerRepeatData.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerRepeatDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerTimeDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerWeekly.cpp
# End Source File
# Begin Source File

SOURCE=.\SchedulerYearly.cpp
# End Source File
# Begin Source File

SOURCE=.\SpinInput.cpp
# End Source File
# Begin Source File

SOURCE=.\SplashDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\TableBase.cpp
# End Source File
# Begin Source File

SOURCE=.\TimeFunc.cpp
# End Source File
# Begin Source File

SOURCE=.\ToDoList.cpp
# End Source File
# Begin Source File

SOURCE=.\ToDoListCategoryDB.cpp
# End Source File
# Begin Source File

SOURCE=.\ToDoListDB.cpp
# End Source File
# Begin Source File

SOURCE=.\ToDoListDetails.cpp
# End Source File
# Begin Source File

SOURCE=.\ToDoListList.cpp
# End Source File
# Begin Source File

SOURCE=.\ToDoListShowDlg.cpp
# End Source File
# Begin Source File

SOURCE=.\Toolbar.cpp
# End Source File
# Begin Source File

SOURCE=.\ToolbarButton.cpp
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File

SOURCE=.\AddressBook.h
# End Source File
# Begin Source File

SOURCE=.\AddressBookCategoryDB.h
# End Source File
# Begin Source File

SOURCE=.\AddressBookDB.h
# End Source File
# Begin Source File

SOURCE=.\AddressBookDBDef.h
# End Source File
# Begin Source File

SOURCE=.\AddressBookDetails.h
# End Source File
# Begin Source File

SOURCE=.\AddressBookDlg.h
# End Source File
# Begin Source File

SOURCE=.\AddressBookList.h
# End Source File
# Begin Source File

SOURCE=.\CategoryDB.h
# End Source File
# Begin Source File

SOURCE=.\CategoryDBDef.h
# End Source File
# Begin Source File

SOURCE=.\CategoryDeleteDlg.h
# End Source File
# Begin Source File

SOURCE=.\CategoryEditor.h
# End Source File
# Begin Source File

SOURCE=.\CategoryEditorList.h
# End Source File
# Begin Source File

SOURCE=.\config.h
# End Source File
# Begin Source File

SOURCE=.\CustomFieldDB.h
# End Source File
# Begin Source File

SOURCE=.\CustomFieldDBDef.h
# End Source File
# Begin Source File

SOURCE=.\CustomFieldEditor.h
# End Source File
# Begin Source File

SOURCE=.\DatePicker.h
# End Source File
# Begin Source File

SOURCE=.\DatePickerDlg.h
# End Source File
# Begin Source File

SOURCE=.\Dialog.h
# End Source File
# Begin Source File

SOURCE=.\FindDlg.h
# End Source File
# Begin Source File

SOURCE=.\FindList.h
# End Source File
# Begin Source File

SOURCE=.\FLTKUtil.h
# End Source File
# Begin Source File

SOURCE=.\HelpID.h
# End Source File
# Begin Source File

SOURCE=.\ImageBox.h
# End Source File
# Begin Source File

SOURCE=.\Images.h
# End Source File
# Begin Source File

SOURCE=.\InfoDB.h
# End Source File
# Begin Source File

SOURCE=.\InfoDBDef.h
# End Source File
# Begin Source File

SOURCE=.\InfoGroup.h
# End Source File
# Begin Source File

SOURCE=.\IniDlg.h
# End Source File
# Begin Source File

SOURCE=.\InputBox.h
# End Source File
# Begin Source File

SOURCE=.\InputNotify.h
# End Source File
# Begin Source File

SOURCE=.\LeftGroup.h
# End Source File
# Begin Source File

SOURCE=.\ListByDlg.h
# End Source File
# Begin Source File

SOURCE=.\Messages.h
# End Source File
# Begin Source File

SOURCE=.\Note.h
# End Source File
# Begin Source File

SOURCE=.\NoteDB.h
# End Source File
# Begin Source File

SOURCE=.\NoteDBDef.h
# End Source File
# Begin Source File

SOURCE=.\NoteDetails.h
# End Source File
# Begin Source File

SOURCE=.\NoteEditor.h
# End Source File
# Begin Source File

SOURCE=.\NoteEditorDlg.h
# End Source File
# Begin Source File

SOURCE=.\NoteList.h
# End Source File
# Begin Source File

SOURCE=.\Notes.h
# End Source File
# Begin Source File

SOURCE=.\NotesCategoryDB.h
# End Source File
# Begin Source File

SOURCE=.\NxDbAccess.h
# End Source File
# Begin Source File

SOURCE=.\NxDbColumn.h
# End Source File
# Begin Source File

SOURCE=.\NxDbRow.h
# End Source File
# Begin Source File

SOURCE=.\Options.h
# End Source File
# Begin Source File

SOURCE=.\OptionsDlg.h
# End Source File
# Begin Source File

SOURCE=.\PixilDT.h
# End Source File
# Begin Source File

SOURCE=.\PixilMainWnd.h
# End Source File
# Begin Source File

SOURCE=.\Printer.h
# End Source File
# Begin Source File

SOURCE=.\ScheduleContainer.h
# End Source File
# Begin Source File

SOURCE=.\ScheduleDay.h
# End Source File
# Begin Source File

SOURCE=.\ScheduleEvent.h
# End Source File
# Begin Source File

SOURCE=.\ScheduleHours.h
# End Source File
# Begin Source File

SOURCE=.\Scheduler.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerCategoryDB.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerChangeTypeDlg.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerDaily.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerDB.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerDBDef.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerDlg.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerMonthly.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerRepeatData.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerRepeatDlg.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerTimeDlg.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerWeekly.h
# End Source File
# Begin Source File

SOURCE=.\SchedulerYearly.h
# End Source File
# Begin Source File

SOURCE=.\SpinInput.h
# End Source File
# Begin Source File

SOURCE=.\SplashDlg.h
# End Source File
# Begin Source File

SOURCE=.\TableBase.h
# End Source File
# Begin Source File

SOURCE=.\TimeFunc.h
# End Source File
# Begin Source File

SOURCE=.\ToDoList.h
# End Source File
# Begin Source File

SOURCE=.\ToDoListCategoryDB.h
# End Source File
# Begin Source File

SOURCE=.\ToDoListDB.h
# End Source File
# Begin Source File

SOURCE=.\ToDoListDBDef.h
# End Source File
# Begin Source File

SOURCE=.\ToDoListDetails.h
# End Source File
# Begin Source File

SOURCE=.\ToDoListList.h
# End Source File
# Begin Source File

SOURCE=.\ToDoListShowDlg.h
# End Source File
# Begin Source File

SOURCE=.\Toolbar.h
# End Source File
# Begin Source File

SOURCE=.\ToolbarButton.h
# End Source File
# Begin Source File

SOURCE=.\VCMemoryLeak.h
# End Source File
# End Group
# Begin Group "Resource Files"

# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File

SOURCE=.\pixil_icon.ico
# End Source File
# End Group
# End Target
# End Project

--- NEW FILE: CategoryEditor.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Category Editor dialog.                                      //
//--------------------------------------------------------------//
#ifndef CATEGORYEDITOR_H_

#define CATEGORYEDITOR_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Button.H>
#include <FL/Fl_Window.H>
#include "CategoryDB.h"
#include "CategoryEditorList.h"
#include "HelpID.h"
#include "PixilMainWnd.h"
class CategoryEditor:public Fl_Window
{
  public:enum Type
    { AddressBook, Notes, Scheduler, ToDoList,
    };
    enum ButtonStatus
    { Disable = 0, Enable = 1,
    };
      CategoryEditor(Type nType,	// Constructor
		     PixilMainWnd * pParent);
     ~CategoryEditor();		// Destructor
    void DeleteCategory(int nRow);	// Delete this row
    void NewCategory();		// Insert a new category
    void Notify(ButtonStatus nMessage);	// Notification from a child widget
    void RenameCategory(int nRow);	// Rename this row
  private:  CategoryDB * m_pDB;
    // Pointer to the database to be used for this dialog
    static const char *m_pszType[4];	// Titles for the dialog based on type of information
    CategoryEditorList *m_pList;	// The list widget in the center of the screen
    Fl_Button *m_pDeleteButton;	// The Delete button
    Fl_Button *m_pHelpButton;	// The Help button
    Fl_Button *m_pNewButton;	// The New button
    Fl_Button *m_pOKButton;	// The OK button
    Fl_Button *m_pRenameButton;	// The Rename button
    enum HelpID m_nHelpID;	// Help ID
    enum Type m_nType;		// Type of categories being edited
    static void OnHelpButton(Fl_Widget * pWidget,	// Help button callback
			     void *pUserData);
    static void OnNewButton(Fl_Widget * pWidget,	// New button callback
			    void *pUserData);
    static void OnDeleteButton(Fl_Widget * pWidget,	// Delete button callback
			       void *pUserData);
    static void OnRenameButton(Fl_Widget * pWidget,	// Rename button callback
			       void *pUserData);
    static bool Validate(const char *pszString,	// Validate a new category
			 Fl_Widget * pThis, void *pData);
};


#endif /*  */

--- NEW FILE: CustomFieldEditor.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Custom Field Editor dialog.                                  //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include "CustomFieldDB.h"
#include "CustomFieldEditor.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT 200
#define DLG_WIDTH  400


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
CustomFieldEditor::CustomFieldEditor(PixilMainWnd * pParent)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Custom Field Editor"))
{
    CustomFieldDB *pCustomFieldDB = CustomFieldDB::GetCustomField();
    int i;
    int nRow;

    // Sort the InfoDB by its key field
    pCustomFieldDB->Sort(0);

    // Create the dialog widgets
    for (i = 0; i < 4; ++i) {
	sprintf(m_szLabel[i], _("Custom Field %d:"), i + 1);
	m_pInput[i] = new Fl_Input(150, 35 * i + 15, 100, 24, m_szLabel[i]);
	m_pInput[i]->textsize(INFOTYPE - 1);
	if (pCustomFieldDB->NumUndeletedRecs() > i) {
	    m_pInput[i]->value(pCustomFieldDB->GetName(i).c_str());
	}
    }

    m_pOKButton = new Fl_Button(310, 15, 80, 24, fl_ok);
    m_pHelpButton = new Fl_Button(310, 55, 80, 24, _("&Help"));
    m_pCancelButton = new Fl_Button(310, 95, 80, 24, fl_cancel);
    m_pCancelButton->shortcut("^[");

    // Finish the dialog
    end();

    // Set the button callbacks
    m_pHelpButton->callback(OnHelpButton);

    // Run this as a modal dialog
    if (DoModal(this, m_pOKButton, m_pCancelButton) == 1) {
	// OK Button was pressed, process the changes
	for (i = 0; i < 4; ++i) {
	    nRow = pCustomFieldDB->FindRow(CUSTOMID, i);
	    if (nRow < 0) {
		// Must insert a new row
		nRow = pCustomFieldDB->Insert(i);
	    }
	    pCustomFieldDB->SetColumn(nRow, CUSTOM, m_pInput[i]->value());
	}

	// Save these chages to disk
	pCustomFieldDB->Save();

	// Notify everyone of Address Book changes
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);
    }
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
CustomFieldEditor::~CustomFieldEditor()
{
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
CustomFieldEditor::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_CUSTOM_FIELD_EDITOR);
}

--- NEW FILE: ToDoList.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Center of the window for the ToDo List display               //
//--------------------------------------------------------------//
#ifndef TODOLIST_H_

#define TODOLIST_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Box.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Group.H>
#include "Messages.h"
#include "ToDoListDetails.h"
#include "ToDoListList.h"
class ToDoList:public Fl_Group
{
  public:ToDoList(Fl_Widget * pParent);
    // Default Constructor
    ~ToDoList();		// Destructor
    inline bool CanPaste() const	// Is there a row that can be pasted
    {
	return (m_vCopyString.size() > 0);
    }
    inline void ChangeComplete(int nRow,	// The completed flag has been changed in the list, tell the details
			       int nComplete)
    {
	m_pToDoListDetails->ChangeComplete(nRow, nComplete);
    }
    inline void ChangeTime(int nRow,	// The due date/completed date has been changed in the list, tell the details
			   time_t nTime)
    {
	m_pToDoListDetails->ChangeTime(nRow, nTime);
    }
    int Copy(int nRow);		// Copy a row to m_strCopyString
    int Cut(int nRow);		// Cut a row to m_strCopyString
    void Delete(int nRow);	// Delete a note
    inline void DisplayRow(int nRow,	// Display a particular row from the Notes List
			   int nRows)
    {
	m_pToDoListDetails->DisplayRow(nRow, nRows);
    }
    void EditNew();		// Insertion of a new Note row has been requested
    inline void Filter(int nCategory)	// Filter rows based on category
    {
	m_pToDoListList->Filter(nCategory);
    }
    int Message(PixilDTMessage nMessage,	// Notification from the parent widget
		int nInfo);
    int Paste();		// Paste the most recently cut/copied row
    inline int SaveDetailChanges()	// Save any outstanding changes on the details window (return of 0 indicates the user said not to save)
    {
	return (m_pToDoListDetails->SaveChanges(true));
    }
    void ViewShow();		// Request for filtering via the Show dialog
  private:bool m_bUndoCut;	// Can a cut be undone
    bool m_bUndoPaste;		// Can a paste be undone
    Fl_Box *m_pTitle;		// The title for the widget
    Fl_Button *m_pNewButton;	// The New button
    Fl_Button *m_pShowButton;	// The Show button
    Fl_Choice *m_pCategory;	// The category choice widget
    Fl_Menu_Item *m_pCategoryMenu;	// Category choice menu
    int m_nLastPaste;		// Last row pasted
    ToDoListDetails *m_pToDoListDetails;	// Details of the current ToDo item
    ToDoListList *m_pToDoListList;	// List of ToDo items
    vector < string > m_vCopyString;	// Most recently cut/copied row
    static void CategorySelected(Fl_Widget * pWidget,	// Category filtering has been changed
				 void *pUserData);
    void FixDeletedCategory(int nCategory);	// Fix any entries with a now deleted category
    inline static void NewButton(Fl_Widget * pWidget,	// Callback for the New button
				 void *pUserData)
    {
	((ToDoList *) (pWidget->parent()))->EditNew();
    }
    void ResetCategoryChoice();	// Re-build the category choice menu
    inline static void ShowButton(Fl_Widget * pWidget,	// Callback for the Show button
				  void *pUserData)
    {
	((ToDoList *) (pWidget->parent()))->ViewShow();
    }
    int Undo();			// Undo the most recent cut/paste
  public:void Refresh()
    {
	m_pToDoListList->Refresh();
    }
};


#endif /*  */

--- NEW FILE: Toolbar.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the main window's toolbar for the Pixil Desktop.   //
//--------------------------------------------------------------//
#include <cassert>
#include "Toolbar.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor.                                                 //
//--------------------------------------------------------------//
Toolbar::Toolbar(int nX,
		 int nY,
		 int nWidth, int nHeight, const ToolbarItem * pToolbarItem)
    :
Fl_Group(nX, nY, nWidth, nHeight, "")
{
    int i;
    int nXPos;

    // Get the number of buttons to be created
    for (i = 0; pToolbarItem[i].m_nType != TOOLBAR_END; ++i);

    // Get memory to cache the toolbar stuff
    m_ppToolbarButton = new PTOOLBARBUTTON[i];
    m_nCount = i;

    // Create each button in turn
    i = 0;
    nXPos = 10;
    do {
	// Create the button
	if (pToolbarItem[i].m_nType != TOOLBAR_GAP
	    && pToolbarItem[i].m_nType != TOOLBAR_END) {
	    m_ppToolbarButton[i] = new ToolbarButton(x() + nXPos,
						     y() + 3,
						     pToolbarItem[i].m_nImage,
						     pToolbarItem[i].
						     m_nDisabledImage,
						     pToolbarItem[i].
						     m_pszTooltip);
	    m_ppToolbarButton[i]->callback(Callback);
	    m_ppToolbarButton[i]->SetCallback(pToolbarItem[i].m_pfnCallback);
	    nXPos += ToolbarButton::GetWidth();
	} else {
	    // No button, just a null pointer and a gap
	    m_ppToolbarButton[i] = NULL;
	    nXPos += (ToolbarButton::GetWidth() >> 1);
	}
	++i;
    } while (pToolbarItem[i].m_nType != TOOLBAR_END);

    // Finish this widget
    end();
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
Toolbar::~Toolbar()
{
    int i;

    for (i = 0; i < m_nCount; ++i) {
	if (m_ppToolbarButton[i] != NULL) {
	    remove(m_ppToolbarButton[i]);
	    delete m_ppToolbarButton[i];
	}
    }
    delete[]m_ppToolbarButton;
}


//--------------------------------------------------------------//
// Translate the widget involved in a callback from a button.   //
//--------------------------------------------------------------//
void
Toolbar::Callback(Fl_Widget * pWidget, void *pUserData)
{
    ((ToolbarButton *) pWidget)->DoCallback();
}


//--------------------------------------------------------------//
// Enable or disable a toolbar button.  The button is located   //
// by the index to its "normal image".                          //
//--------------------------------------------------------------//
void
Toolbar::Enable(int nImage, bool bEnable)
{
    int i;

    // Find the button
    for (i = 0; i < m_nCount; ++i) {
	if (m_ppToolbarButton[i] != NULL) {
	    if (m_ppToolbarButton[i]->GetNormalImage() == nImage) {
		break;
	    }
	}
    }

#ifdef DEBUG
    // Test that the image was found
    assert(i < m_nCount);
#endif

    if (i < m_nCount) {
	// Enable or disable this button
	m_ppToolbarButton[i]->Enable(bEnable);
    }
}

--- NEW FILE: PixilMainWnd.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the main window for the Pixil Desktop.             //
//--------------------------------------------------------------//
#ifndef PIXILMAINWND_H_

#define PIXILMAINWND_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Window.H>
#include "InfoGroup.h"
#include "LeftGroup.h"
#include "Toolbar.h"
class PixilMainWnd:public Fl_Window
{
  public:PixilMainWnd(int argc,
		 // Constructor
		 char **argv);
     ~PixilMainWnd();		// Destructor
    void Notify(PixilDTMessage nMessage,	// Process a notification from a child widget
		int nInfo);
    inline void ResetCursor()	// Set the cursor back to its original value
    {
	cursor(FL_CURSOR_DEFAULT);
    }
    inline void SetCursor(Fl_Cursor nCursor)	// Set the cursor for this window
    {
	cursor(nCursor);
    }
  protected:int handle(int nEvent);
    // Event handler, keep escape key from closing this window
  private:Fl_Cursor m_nCursor;
    // The original cursor for this window
    static const Fl_Menu_Item m_MenuItems[];	// Menu definition
    Fl_Menu_Item *m_pTranslatedMenuItems;	// Translated menu definition
    InfoGroup *m_pInfoGroup;	// Main sub-window
    LeftGroup *m_pLeftGroup;	// Group for the left of the main window
    PixilDTMessage m_nCurrentDisplay;	// Type of info currently being displayed
    Toolbar *m_pToolbar;	// Toolbar for the window
    static const ToolbarItem m_ToolbarItem[];	// Toolbar definitions
    static void Callback(Fl_Widget * pWidget, void *pData);	// Used to close the program nicely
    static void EditCopy(Fl_Widget * pWidget, void *pData);	// Edit/Copy menu selection
    static void EditCut(Fl_Widget * pWidget, void *pData);	// Edit/Cut menu selection
    static void EditDelete(Fl_Widget * pWidget, void *pData);	// Edit/Delete menu selection
    static void EditFind(Fl_Widget * pWidget, void *pData);	// Edit/Find menu selection
    static void EditNew(Fl_Widget * pWidget, void *pData);	// Edit/New menu selection
    static void EditPaste(Fl_Widget * pWidget, void *pData);	// Edit/Paste menu selection
    static void EditUndo(Fl_Widget * pWidget, void *pData);	// Edit/Undo menu selection
    void EnableMenuItem(const char *pszTopMenu,	// Enable/Disable Show/Hide a menu item
			const char *pszSubMenu, bool bEnable, bool bVisible);
    static void FileExit(Fl_Widget * pWidget, void *pData);	// File/Exit menu selection
    static void FilePageSetup(Fl_Widget * pWidget, void *pData)	// File/Page Setup menu selection
    {
    }
    static void FilePrint(Fl_Widget * pWidget, void *pData);	// File/Print menu selection
    static void FileSaveAll(Fl_Widget * pWidget, void *pData)	// File/Save All menu selection
    {
    }
    void FixMenu();		// Enable/disable menu selection based on current display
    static void HelpAbout(Fl_Widget * pWidget, void *pData);	// Help/About Pixil Desktop menu selection
    static void HelpHelp(Fl_Widget * pWidget, void *pData);	// Help/PixilDesktopHelp menu selection
    static void HelpOnlineSupport(Fl_Widget * pWidget, void *pData)	// Help/Online Support menu selection
    {
    }
    static void HelpQuickTour(Fl_Widget * pWidget, void *pData)	// Help/QuickTour menu selection
    {
    }
    static void HelpPixilOnWeb(Fl_Widget * pWidget, void *pData)	// Help/Pixil on the Web menu selection
    {
    }
    int SetCurrentDisplay(PixilDTMessage nMessage);	// Set the current display type
    static void SyncPush(Fl_Widget * pWidget, void *pData);
    static void SyncPull(Fl_Widget * pWidget, void *pData);
    static void SyncMerge(Fl_Widget * pWidget, void *pData);
    static void SyncSetup(Fl_Widget * pWidget, void *pData)	// Sync/Setup menu selection
    {
    }
    static void ToolsCategories(Fl_Widget * pWidget, void *pData);	// Tools/Categories menu selection
    static void ToolsCustomFields(Fl_Widget * pWidget, void *pData);	// Tools/Custom Fields menu selection
    static void ToolsOptions(Fl_Widget * pWidget, void *pData);	// Tools/Options menu selection
    static void ToolsPurgeCompletedToDos(Fl_Widget * pWidget, void *pData)	// Tools/Purge Completed ToDo's menu selection
    {
    }
    static void ToolsPurgeEvents(Fl_Widget * pWidget, void *pData)	// Tools/Purge Events menu selection
    {
    }
    static void ViewAddressBook(Fl_Widget * pWidget, void *pData);	// View/Address Book menu selection
    static void ViewHidePrivate(Fl_Widget * pWidget, void *pData)	// View/Hide Private Records menu selection
    {
    }
    static void ViewListBy(Fl_Widget * pWidget, void *pData);	// View/List By menu selection
    static void ViewNotes(Fl_Widget * pWidget, void *pData);	// View/Notes menu selection
    static void ViewScheduler(Fl_Widget * pWidget, void *pData);	// View/Scheduler menu selection
    static void ViewShow(Fl_Widget * pWidget, void *pData);	// View/Show (for ToDo List) menu selection
    static void ViewShowPrivate(Fl_Widget * pWidget, void *pData)	// View/Show Private Records menu selection
    {
    }
    static void ViewTodoList(Fl_Widget * pWidget, void *pData);	// View/ToDo List menu selection
};


#endif /*  */

--- NEW FILE: NxDb0003.txt ---
add_info
#1 0,"Work"
#2 1,"Home"
#3 2,"Fax"
#4 3,"Mobile"
#5 4,"Pager"
#6 5,"E-Mail"
#7 6,"Web Page"

--- NEW FILE: Toolbar.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the main window's toolbar for the Pixil Desktop.   //
//--------------------------------------------------------------//
#ifndef TOOLBAR_H_

#define TOOLBAR_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <string>
#include <FL/Fl_Group.H>
#include "ToolbarButton.h"
using namespace std;
typedef ToolbarButton *PTOOLBARBUTTON;

//--------------------------------------------------------------//
// External structure for item definitions.                     //
//--------------------------------------------------------------//
typedef struct tagToolbarItem
{
    int m_nType;		// The type of entry
    const char *m_pszTooltip;	// Tooltip text
    Fl_Callback *m_pfnCallback;	// The callback if this is selected
    int m_nImage;		// The image for this button
    int m_nDisabledImage;	// The image when disabled
}
ToolbarItem;

//--------------------------------------------------------------//
// Values for the button type.                                  //
//--------------------------------------------------------------//
#define TOOLBAR_END    0
#define TOOLBAR_BUTTON 1
#define TOOLBAR_GAP    2

//--------------------------------------------------------------//
// The class.                                                   //
//--------------------------------------------------------------//
class Toolbar:public Fl_Group
{
  public:Toolbar(int nX,	// Constructor
	    int nY, int nWidth, int nHeight,
	    const ToolbarItem * pToolbarItem);
     ~Toolbar();		// Destructor
    void Enable(int nEnabledImage,	// Enable or disable a button
		bool bEnable = true);
  private:int m_nCount;	// Number of ToolbarButtons
    ToolbarButton **m_ppToolbarButton;	// The internal copy of the toolbar items
    static void Callback(Fl_Widget * pWidget,	// Translate widget involved in the callback
			 void *pUserData);
};


#endif /*  */

--- NEW FILE: CategoryEditor.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Category Editor dialog.                                      //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include "AddressBookCategoryDB.h"
#include "CategoryEditor.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "InputBox.h"
#include "NotesCategoryDB.h"
#include "Options.h"
#include "PixilDT.h"
#include "SchedulerCategoryDB.h"
#include "ToDoListCategoryDB.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT 400
#define DLG_WIDTH  340


//--------------------------------------------------------------//
// Dialog titles                                                //
//--------------------------------------------------------------//
const char *
    CategoryEditor::m_pszType[4] = {
    N_("Edit Address Book Categories"),
    N_("Edit Note Categories"),
    N_("Edit Scheduler Categories"),
    N_("Edit ToDo List Categories"),
};


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
CategoryEditor::CategoryEditor(Type nType, PixilMainWnd * pParent)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _(m_pszType[nType]))
{
    // Get the correct set of categories
    m_nType = nType;
    switch (nType) {
    case AddressBook:
	m_pDB = AddressBookCategoryDB::GetAddressBookCategoryDB();
	m_nHelpID = HELP_ADDRESS_BOOK_CATEGORY;
	break;

    case Notes:
	m_pDB = NotesCategoryDB::GetNotesCategoryDB();
	m_nHelpID = HELP_NOTES_CATEGORY;
	break;

    case Scheduler:
	m_pDB = SchedulerCategoryDB::GetSchedulerCategoryDB();
	m_nHelpID = HELP_SCHEDULER_CATEGORY;
	break;

    case ToDoList:
	m_pDB = ToDoListCategoryDB::GetToDoListCategoryDB();
	m_nHelpID = HELP_TODO_LIST_CATEGORY;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown type of information
#endif
	m_pDB = NULL;
    }

    // Create the dialog widgets
    m_pList = new CategoryEditorList(10, 10, 200, 380, m_pDB);
    m_pOKButton = new Fl_Button(230, 10, 80, 24, fl_ok);
    m_pNewButton = new Fl_Button(230, 45, 80, 24, _("&New"));
    m_pDeleteButton = new Fl_Button(230, 80, 80, 24, _("&Delete"));
    m_pRenameButton = new Fl_Button(230, 115, 80, 24, _("&Rename"));
    m_pHelpButton = new Fl_Button(230, 150, 80, 24, _("&Help"));

    // Finish the dialog
    end();

    // Set the button callbacks
    m_pNewButton->callback(OnNewButton);
    m_pDeleteButton->callback(OnDeleteButton);
    m_pRenameButton->callback(OnRenameButton);
    m_pHelpButton->callback(OnHelpButton);

    // Add the categories to the list widget
    m_pList->Refresh();

    // Run this as a modal dialog
    DoModal(this, m_pOKButton, NULL);
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
CategoryEditor::~CategoryEditor()
{
}


//--------------------------------------------------------------//
// Delete a category by row.                                    //
//--------------------------------------------------------------//
void
CategoryEditor::DeleteCategory(int nRow)
{
    int nCategory;

#ifdef DEBUG
    assert(nRow > 0 && nRow < m_pList->rows());
#endif

    // Only run if the current item is not the "Unfiled" category
    if (nRow > 0) {
	int nContinue;

	if (Options::GetConfirmDelete() == true) {
	    nContinue = fl_ask(_("Delete Category %s ?"),
			       m_pDB->GetCategory(nRow).c_str());
	} else {
	    nContinue = 1;
	}

	if (nContinue == 1) {
	    nCategory = m_pDB->GetCategoryID(nRow);
	    m_pDB->Delete(nRow);
	    m_pDB->Save();
	    m_pList->Refresh();
	    PixilDT::GetApp()->GetMainWindow()->Notify(CATEGORY_DELETED,
						       nCategory);
	}
    }
}


//--------------------------------------------------------------//
// Notification from a child widget.                            //
//--------------------------------------------------------------//
void
CategoryEditor::Notify(ButtonStatus nMessage)
{
    if (nMessage == Disable) {
	// Disable the delete and rename buttons
	m_pDeleteButton->deactivate();
	m_pRenameButton->deactivate();
    } else {
	// Enable the delete and rename buttons
	m_pDeleteButton->activate();
	m_pRenameButton->activate();
    }
}


//--------------------------------------------------------------//
// Insert a new category.                                       //
//--------------------------------------------------------------//
void
CategoryEditor::NewCategory()
{
    AddressBookCategoryDB *pDB =
	AddressBookCategoryDB::GetAddressBookCategoryDB();
    string strNewCategory;
    InputBox *pInputBox;

    // Get the new category name to be entered
    pInputBox = new InputBox(_("New Category"),
			     PixilDT::GetApp()->GetMainWindow(),
			     "",
			     pDB->GetColumnSize(CAT),
			     m_nHelpID,
			     Validate,
			     this,
			     NULL, _("Please Enter the New Category Name:"));
    strNewCategory = pInputBox->GetEntry();
    delete pInputBox;

    // Insert this category if one was entered
    if (strNewCategory.length() != 0) {
	int nRow = m_pDB->Insert(-1);	// -1 for next highest key value

	m_pDB->SetCategory(nRow, strNewCategory.c_str());
	m_pDB->Save();
	m_pList->Refresh();
	PixilDT::GetApp()->GetMainWindow()->Notify(CATEGORY_ADDED, 0);
    }
}


//--------------------------------------------------------------//
// Delete button was clicked (static callback).                 //
//--------------------------------------------------------------//
void
CategoryEditor::OnDeleteButton(Fl_Widget * pWidget, void *pUserData)
{
    CategoryEditor *pThis =
	dynamic_cast < CategoryEditor * >(pWidget->parent());

    pThis->DeleteCategory(pThis->m_pList->row());
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
CategoryEditor::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_CATEGORY_EDITOR);
}


//--------------------------------------------------------------//
// New button was clicked (static callback).                    //
//--------------------------------------------------------------//
void
CategoryEditor::OnNewButton(Fl_Widget * pWidget, void *pUserData)
{
    CategoryEditor *pThis =
	dynamic_cast < CategoryEditor * >(pWidget->parent());

    pThis->NewCategory();
}


//--------------------------------------------------------------//
// Rename button was clicked (static callback).                 //
//--------------------------------------------------------------//
void
CategoryEditor::OnRenameButton(Fl_Widget * pWidget, void *pUserData)
{
    CategoryEditor *pThis =
	dynamic_cast < CategoryEditor * >(pWidget->parent());

    pThis->RenameCategory(pThis->m_pList->row());
}


//--------------------------------------------------------------//
// Rename a category.                                           //
//--------------------------------------------------------------//
void
CategoryEditor::RenameCategory(int nRow)
{
    AddressBookCategoryDB *pDB =
	AddressBookCategoryDB::GetAddressBookCategoryDB();
    InputBox *pInputBox;
    int nCategory;
    string strNewCategory;

#ifdef DEBUG
    assert(nRow >= 0 && nRow < m_pList->rows());
#endif

    // Only run if the current item is not the "Unfiled" category
    if (nRow > 0) {
	// Get the new category name to be entered
	nCategory = m_pDB->GetCategoryID(nRow);
	pInputBox = new InputBox(_("Rename Category"),
				 PixilDT::GetApp()->GetMainWindow(),
				 m_pDB->GetCategory(nRow).c_str(),
				 pDB->GetColumnSize(CAT),
				 m_nHelpID,
				 Validate,
				 this,
				 reinterpret_cast < void *>(nCategory),
				 _("Please Enter the New Category Name:"));
	strNewCategory = pInputBox->GetEntry();
	delete pInputBox;

	// Change this category if one was entered
	if (strNewCategory.length() > 0) {
	    m_pDB->SetCategory(nRow, strNewCategory.c_str());
	    m_pDB->Save();
	    m_pList->Refresh();
	    PixilDT::GetApp()->GetMainWindow()->Notify(CATEGORY_RENAMED, 0);
	}
    }
}


//--------------------------------------------------------------//
// Validate a new category name (static callback).              //
//--------------------------------------------------------------//
bool
CategoryEditor::Validate(const char *pszString,
			 Fl_Widget * pThis, void *pUserData)
{
    // Test this name against all existing category names
    return (((CategoryEditor *) pThis)->m_pDB->
	    TestDuplicate(pszString, pUserData));
}

--- NEW FILE: OptionsDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Global Options Dialog.                                       //
//--------------------------------------------------------------//
#ifndef OPTIONSDLG_H_

#define OPTIONSDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Window.H>
class OptionsDlg:public Fl_Window
{
  public:OptionsDlg(Fl_Widget * pParent);
    // Constructor
    ~OptionsDlg();		// Destructor
    int DoModal();		// Run the modal dialog
  private:  Fl_Button * m_pBrowseButton;
    // Browse for data directory
    Fl_Button *m_pCancelButton;	// Cancel button
    Fl_Button *m_pHelpButton;	// Help button
    Fl_Button *m_pOKButton;	// OK Button
    Fl_Check_Button *m_pConfirmDelete;	// Confirm deletes check button
    Fl_Choice *m_pAppChoice;	// Startup application
    Fl_Choice *m_pDayBegins;	// Hour the day begins
    Fl_Choice *m_pWeekBegins;	// Day the week begins
    Fl_Input *m_pDataDir;	// Data directory
    Fl_Menu_Item *m_pMenuApp;	// Menu for m_pAppChoice
    Fl_Menu_Item *m_pMenuDayBegins;	// Menu for m_pDayBegins
    Fl_Menu_Item *m_pMenuWeekBegins;	// Menu for m_pWeekBegins
    static void OnBrowseButton(Fl_Widget * pWidget,	// Process a click on the browse button
			       void *pUserData);
    static void OnHelpButton(Fl_Widget * pWidget,	// Process a click on the help button
			     void *pUserData);
    static bool Validate(const char *pszString,	// Validate a new data directory
			 Fl_Widget * pThis, void *pData);
};


#endif /*  */

--- NEW FILE: AddressBookDBDef.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Address Book database definition fields.                     //
//--------------------------------------------------------------//
#ifndef ADDRESSBOOKDBDEF_H_

#define ADDRESSBOOKDBDEF_H_

// Contacts Fields
field cFields[] = {
    {
     'i', 1, 0}
    ,				// Field 0:RECNO
    {
     'i', 1, 0}
    ,				//       1:CAT
    {
     'i', 1, 0}
    ,				//          2:SHOW
    {
     'c', AB_TEXT, 0}
    ,				//       3:LASTNAME
    {
     'c', AB_TEXT, 0}
    ,				//       4:FIRSTNAME
    {
     'c', AB_TEXT, 0}
    ,				//       5:COMPANY
    {
     'c', AB_TEXT, 0}
    ,				//       6:TITLE
    {
     'i', 1, 0}
    ,				//          7:DEP1ID
    {
     'i', 1, 0}
    ,				//          8:DEP2ID
    {
     'i', 1, 0}
    ,				//          9:DEP3ID
    {
     'i', 1, 0}
    ,				//         10:DEP4ID
    {
     'i', 1, 0}
    ,				//         11:DEP5ID
    {
     'i', 1, 0}
    ,				//         12:DEP6ID
    {
     'i', 1, 0}
    ,				//         13:DEP7ID
    {
     'c', AB_TEXT, 0}
    ,				//      14:DEP1
    {
     'c', AB_TEXT, 0}
    ,				//      15:DEP2
    {
     'c', AB_TEXT, 0}
    ,				//      16:DEP3
    {
     'c', AB_TEXT, 0}
    ,				//      17:DEP4
    {
     'c', AB_TEXT, 0}
    ,				//      18:DEP5
    {
     'c', AB_TEXT, 0}
    ,				//      19:DEP6
    {
     'c', AB_TEXT, 0}
    ,				//      20:DEP7
    {
     'c', AB_DBL_TEXT, 0}
    ,				//      21:ADDRESS
    {
     'c', AB_TEXT, 0}
    ,				//      22:CITY
    {
     'c', AB_TEXT, 0}
    ,				//      23:REGION
    {
     'c', AB_TEXT, 0}
    ,				//      24:POSTALCODE
    {
     'c', AB_TEXT, 0}
    ,				//      25:COUNTRY
    {
     'c', AB_DATE, 0}
    ,				//      26:BDAY
    {
     'c', AB_DATE, 0}
    ,				//      27:ANNIV
    {
     'c', AB_TEXT, 0}
    ,				//      28:CUST1
    {
     'c', AB_TEXT, 0}
    ,				//      29:CUST2
    {
     'c', AB_TEXT, 0}
    ,				//      30:CUST3
    {
     'c', AB_TEXT, 0}
    ,				//      31:CUST4
    {
     'c', AB_NOTEDB, 0}
    ,				//      32:NOTE
    {
     0}
};


// Database
fildes cFile = {		// system file
    0, 0, 0,			// database file
    "dbf",			// extension
    33,				// nfields
    &cFields[0]			// fieldlist
};


#endif /*  */

--- NEW FILE: CategoryEditorList.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Category Editor List widget.                                 //
//--------------------------------------------------------------//
#ifndef CATEGORYEDITORLIST_H_

#define CATEGORYEDITORLIST_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <vector>
#include <Flek/Flv_List.H>
#include "CategoryDB.h"
using namespace std;
class CategoryEditorList:public Flv_List
{
  public:CategoryEditorList(int nX,
		       // Constructor
		       int nY, int nWidth, int nHeight, CategoryDB * pDB);
     ~CategoryEditorList();	// Destructor
    void Refresh();		// Refresh this list from the data base
  protected:void draw_row(int nOffset,
		  // Draw a row
		  int &nX, int &nY, int &nWidth, int &nHeight, int nRow);
    int handle(int nEvent);	// Handle events
  private:  CategoryDB * m_pDB;
    // Pointer to the database to be used for this dialog
    int m_nCurrentRow;		// Currently selected row - used in callback function
      vector < int >m_vnRow;	// Row numbers displayed in the list
    static void Callback(Fl_Widget * pWidget,	// FLTK callback function
			 void *pUserData);
};


#endif /*  */

--- NEW FILE: AddressBookDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Address Book Dialog.                                         //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Return_Button.H>
#include "AddressBookCategoryDB.h"
#include "AddressBookDB.h"
#include "AddressBookDlg.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "Messages.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT       480
#define DLG_INDENT       100
#define DLG_WIDTH        520


//--------------------------------------------------------------//
// Constructor, nRow is the row number in the address book      //
// database as currently sorted or a -1 if this is to be a new  //
// row.                                                         //
//--------------------------------------------------------------//
AddressBookDlg::AddressBookDlg(int nRow, Fl_Widget * pParent)
    :
Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Edit Address"))
{
    // Get the record number for this address book key
    if (nRow < 0) {
	// New row
	m_nRow = -1;
    } else {
	m_nRow = nRow;
    }

    // Create the dialog widgets
    // Tab/notebook widget first
    m_pTabs = new Fl_Tabs(DLG_BORDER,
			  DLG_BORDER,
			  w() - 3 * DLG_BORDER - DLG_BUTTON_WIDTH,
			  h() - 2 * DLG_BORDER);

    // Add the first page to the tab
    CreatePage1();

    // Add the second page to the tab
    CreatePage2();

    // Add the third page to the tab
    CreatePage3();

    // Finish with the tab widget
    m_pTabs->end();

    // Create the buttons
    m_pOKButton = new Fl_Return_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				       DLG_BORDER + DLG_TAB_HEIGHT,
				       DLG_BUTTON_WIDTH,
				       DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton = new Fl_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				    2 * DLG_BORDER + DLG_BUTTON_HEIGHT +
				    DLG_TAB_HEIGHT, DLG_BUTTON_WIDTH,
				    DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				  3 * DLG_BORDER + 2 * DLG_BUTTON_HEIGHT +
				  DLG_TAB_HEIGHT, DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);
    CreateCategoryChoice();

    m_pTabs->show();
    end();

    // The DoModal method will call show on this window
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
AddressBookDlg::~AddressBookDlg()
{
    int i;

    // Free the Info choices
    for (i = 0; i < 7; ++i) {
	FreeTranslatedMenu(m_pTranslatedMenu[i]);
    }

    // Free the Category choice
    FreeTranslatedMenu(m_pTranslatedCategoryMenu);
}


//--------------------------------------------------------------//
// Create the category selection widget                         //
//--------------------------------------------------------------//
void
AddressBookDlg::CreateCategoryChoice()
{
    AddressBookCategoryDB *pAddressBookCategoryDB =
	AddressBookCategoryDB::GetAddressBookCategoryDB();

    // Create the widget
    m_pCategory = new Fl_Choice(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
				DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);

    // Create the menu
    m_pTranslatedCategoryMenu =
	pAddressBookCategoryDB->GetCategoryMenu(false);

    // Select the current category
    if (m_nRow >= 0) {
	int nCategory =
	    pAddressBookCategoryDB->FindRow(CATID,
					    AddressBookDB::
					    GetAddressBookDB()->
					    GetCategory(m_nRow));

	if (nCategory < 0) {
	    // Fix if invalid category
	    nCategory = 0;
	}
	m_pCategory->value(nCategory);
    }
    // Set the menu
    m_pCategory->menu(m_pTranslatedCategoryMenu);
}


//--------------------------------------------------------------//
// Create the first tab page                                    //
//--------------------------------------------------------------//
void
AddressBookDlg::CreatePage1()
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int i;
    int nWidth;
    int nX;
    int nY;

    // Create this page
    m_pPage[0] = new Fl_Group(DLG_BORDER,
			      DLG_BORDER + DLG_TAB_HEIGHT,
			      m_pTabs->w() - 2 * DLG_BORDER,
			      m_pTabs->h() - 2 * DLG_BORDER, _("Name"));
    nWidth = m_pPage[0]->w();
    nX = m_pPage[0]->x();
    nY = m_pPage[0]->y();

    // Create the input fields
    m_pLastName = new Fl_Input(nX + DLG_INDENT,
			       nY + DLG_BORDER,
			       m_pPage[0]->w() - DLG_INDENT,
			       DLG_INPUT_HEIGHT, _("Last Name:"));
    m_pLastName->maximum_size(pAddressBookDB->GetColumnSize(AB_LASTNAME));
    m_pFirstName = new Fl_Input(nX + DLG_INDENT,
				nY + 2 * DLG_BORDER + DLG_INPUT_HEIGHT,
				m_pPage[0]->w() - DLG_INDENT,
				DLG_INPUT_HEIGHT, _("First Name:"));
    m_pFirstName->maximum_size(pAddressBookDB->GetColumnSize(AB_FIRSTNAME));
    m_pTitle = new Fl_Input(nX + DLG_INDENT,
			    nY + 3 * DLG_BORDER + 2 * DLG_INPUT_HEIGHT,
			    m_pPage[0]->w() - DLG_INDENT,
			    DLG_INPUT_HEIGHT, _("Title:"));
    m_pTitle->maximum_size(pAddressBookDB->GetColumnSize(AB_TITLE));
    m_pCompany = new Fl_Input(nX + DLG_INDENT,
			      nY + 4 * DLG_BORDER + 3 * DLG_INPUT_HEIGHT,
			      m_pPage[0]->w() - DLG_INDENT,
			      DLG_INPUT_HEIGHT, _("Company:"));
    m_pCompany->maximum_size(pAddressBookDB->GetColumnSize(AB_COMPANY));
    m_pMessage = new Fl_Box(nX + 0,
			    nY + 5 * DLG_BORDER + 4 * DLG_INPUT_HEIGHT,
			    DLG_INDENT, DLG_INPUT_HEIGHT, _("Show in list:"));
    m_pMessage->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);

    // Set up the Info fields
    for (i = 0; i < 7; ++i) {
	m_pRadioButton[i] =
	    new Fl_Check_Button(nX + DLG_INDENT - DLG_RADIO_SIZE,
				nY + 6 * DLG_BORDER + 5 * DLG_INPUT_HEIGHT +
				i * (DLG_BORDER + DLG_INPUT_HEIGHT),
				DLG_RADIO_SIZE, DLG_INPUT_HEIGHT);
	m_pRadioButton[i]->type(FL_RADIO_BUTTON);
	m_pRadioButton[i]->down_box(FL_ROUND_DOWN_BOX);
	m_pInfoChoice[i] = new Fl_Choice(nX + DLG_INDENT,
					 nY + 6 * DLG_BORDER +
					 5 * DLG_INPUT_HEIGHT +
					 i * (DLG_BORDER + DLG_INPUT_HEIGHT),
					 (nWidth - DLG_INDENT -
					  DLG_BORDER) / 3, DLG_INPUT_HEIGHT);
	FillInfoChoice(m_pInfoChoice[i], i);
	m_pInfo[i] =
	    new Fl_Input(nX + DLG_INDENT +
			 (nWidth - DLG_INDENT - DLG_BORDER) / 3 + DLG_BORDER,
			 nY + 6 * DLG_BORDER + 5 * DLG_INPUT_HEIGHT +
			 i * (DLG_BORDER + DLG_INPUT_HEIGHT),
			 nWidth - DLG_INDENT - DLG_BORDER - (nWidth -
							     DLG_INDENT -
							     DLG_BORDER) / 3,
			 DLG_INPUT_HEIGHT);
	m_pInfo[i]->maximum_size(pAddressBookDB->GetColumnSize(AB_DEP1 + i));
    }

    // Set the initial data into the dialog if this is a changed row
    if (m_nRow >= 0) {
	int nSetting;

	// Set the text fields
	m_pLastName->value(pAddressBookDB->GetLastName(m_nRow).c_str());
	m_pFirstName->value(pAddressBookDB->GetFirstName(m_nRow).c_str());
	m_pTitle->value(pAddressBookDB->GetTitle(m_nRow).c_str());
	m_pCompany->value(pAddressBookDB->GetCompany(m_nRow).c_str());

	// Determine which show radio button to be used
	nSetting = pAddressBookDB->GetShowFlag(m_nRow);
	if (nSetting < 0 || nSetting >= 6) {
	    nSetting = 0;
	}
	m_pRadioButton[nSetting]->value(1);

	// Set the Info data
	for (i = 0; i < 7; ++i) {
	    m_pInfoChoice[i]->value(pAddressBookDB->GetInfoID(m_nRow, i));
	    m_pInfo[i]->value(pAddressBookDB->GetInfo(m_nRow, i).c_str());
	}
    }

    m_pPage[0]->end();
}


//--------------------------------------------------------------//
// Create the second tab page                                   //
//--------------------------------------------------------------//
void
AddressBookDlg::CreatePage2()
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int i;
    int nX;
    int nY;

    // Create this page
    m_pPage[1] = new Fl_Group(DLG_BORDER,
			      DLG_BORDER + DLG_TAB_HEIGHT,
			      m_pTabs->w() - 2 * DLG_BORDER,
			      m_pTabs->h() - 2 * DLG_BORDER, _("Address"));
    nX = m_pPage[0]->x();
    nY = m_pPage[0]->y();

    // Create the input fields
    m_pAddress = new Fl_Input(nX + DLG_INDENT,
			      nY + DLG_BORDER,
			      m_pPage[1]->w() - DLG_INDENT - DLG_BORDER,
			      DLG_INPUT_HEIGHT, _("Address:"));
    m_pAddress->maximum_size(pAddressBookDB->GetColumnSize(AB_ADDRESS));
    m_pCity = new Fl_Input(nX + DLG_INDENT,
			   nY + 2 * DLG_BORDER + DLG_INPUT_HEIGHT,
			   m_pPage[1]->w() - DLG_INDENT - DLG_BORDER,
			   DLG_INPUT_HEIGHT, _("City:"));
    m_pCity->maximum_size(pAddressBookDB->GetColumnSize(AB_CITY));
    m_pRegion = new Fl_Input(nX + DLG_INDENT,
			     nY + 3 * DLG_BORDER + 2 * DLG_INPUT_HEIGHT,
			     m_pPage[1]->w() - DLG_INDENT - DLG_BORDER,
			     DLG_INPUT_HEIGHT, _("State:"));
    m_pRegion->maximum_size(pAddressBookDB->GetColumnSize(AB_REGION));
    m_pPostalCode = new Fl_Input(nX + DLG_INDENT,
				 nY + 4 * DLG_BORDER + 3 * DLG_INPUT_HEIGHT,
				 m_pPage[1]->w() - DLG_INDENT - DLG_BORDER,
				 DLG_INPUT_HEIGHT, _("Zip:"));
    m_pPostalCode->maximum_size(pAddressBookDB->GetColumnSize(AB_POSTALCODE));
    m_pCountry = new Fl_Input(nX + DLG_INDENT,
			      nY + 5 * DLG_BORDER + 4 * DLG_INPUT_HEIGHT,
			      m_pPage[1]->w() - DLG_INDENT - DLG_BORDER,
			      DLG_INPUT_HEIGHT, _("Country:"));
    m_pCountry->maximum_size(pAddressBookDB->GetColumnSize(AB_COUNTRY));

    // Create the anniversary and birthday input fields
    m_pBirthday = new Fl_Input(nX + DLG_INDENT,
			       nY + 7 * DLG_BORDER + 6 * DLG_INPUT_HEIGHT,
			       m_pPage[1]->w() - DLG_INDENT - DLG_BORDER,
			       DLG_INPUT_HEIGHT, _("Birthday:"));
    m_pBirthday->maximum_size(pAddressBookDB->GetColumnSize(AB_BDAY));
    m_pAnniversary = new Fl_Input(nX + DLG_INDENT,
				  nY + 8 * DLG_BORDER + 7 * DLG_INPUT_HEIGHT,
				  m_pPage[1]->w() - DLG_INDENT - DLG_BORDER,
				  DLG_INPUT_HEIGHT, _("Anniversary:"));
    m_pAnniversary->maximum_size(pAddressBookDB->GetColumnSize(AB_ANNIV));

    for (i = 0; i < 4; ++i) {
	m_strCustomField[i] = pAddressBookDB->GetCustomFieldName(i) + ":";
	m_pCustom[i] = new Fl_Input(nX + DLG_INDENT,
				    nY + 10 * DLG_BORDER +
				    9 * DLG_INPUT_HEIGHT + i * (DLG_BORDER +
								DLG_INPUT_HEIGHT),
				    m_pPage[1]->w() - DLG_INDENT - DLG_BORDER,
				    DLG_INPUT_HEIGHT,
				    m_strCustomField[i].c_str());
	m_pCustom[i]->maximum_size(pAddressBookDB->
				   GetColumnSize(AB_CUST1 + i));
    }

    // Set the initial data into the dialog if this is a changed row
    if (m_nRow >= 0) {
	// Set the text fields
	m_pAddress->value(pAddressBookDB->GetAddress(m_nRow).c_str());
	m_pCity->value(pAddressBookDB->GetCity(m_nRow).c_str());
	m_pRegion->value(pAddressBookDB->GetRegion(m_nRow).c_str());
	m_pPostalCode->value(pAddressBookDB->GetPostalCode(m_nRow).c_str());
	m_pCountry->value(pAddressBookDB->GetCountry(m_nRow).c_str());
	m_pBirthday->value(pAddressBookDB->GetBirthday(m_nRow).c_str());
	m_pAnniversary->value(pAddressBookDB->GetAnniversary(m_nRow).c_str());

	// Set the Custom Field data
	for (i = 0; i < 4; ++i) {
	    m_pCustom[i]->value(pAddressBookDB->GetCustomField(m_nRow, i).
				c_str());
	}
    }

    m_pPage[1]->end();
}


//--------------------------------------------------------------//
// Create the third tab page                                    //
//--------------------------------------------------------------//
void
AddressBookDlg::CreatePage3()
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int nX;
    int nY;
    Note *pNote;

    // Create this page
    m_pPage[2] = new Fl_Group(DLG_BORDER,
			      DLG_BORDER + DLG_TAB_HEIGHT,
			      m_pTabs->w() - 2 * DLG_BORDER,
			      m_pTabs->h() - 2 * DLG_BORDER, _("Note"));
    nX = m_pPage[0]->x();
    nY = m_pPage[0]->y();

    // Create the note editor
    if (m_nRow == -1) {
	// New item
	pNote = pAddressBookDB->GetNewNote();
    } else {
	pNote = pAddressBookDB->GetNote(m_nRow);
    }
    m_pNoteEditor = new NoteEditor(nX + DLG_BORDER,
				   nY + DLG_BORDER,
				   m_pPage[2]->w() - 2 * DLG_BORDER,
				   m_pPage[2]->h() - 2 * DLG_BORDER,
				   true, pNote);
    m_pNoteEditor->SetDestroyNote(true);

    m_pPage[2]->end();
}


//--------------------------------------------------------------//
// Run the modal dialog                                         //
//--------------------------------------------------------------//
int
AddressBookDlg::DoModal()
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int i;
    int nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

    if (nReturn == 1) {
	// OK button was pressed, update the Address Book record

	// Create a new Address Book record if needed
	if (m_nRow < 0) {
	    m_nRow = pAddressBookDB->Insert();
	}
	// Change all fields
	pAddressBookDB->SetAddress(m_nRow, m_pAddress->value());
	pAddressBookDB->SetAnniversary(m_nRow, m_pAnniversary->value());
	pAddressBookDB->SetBirthday(m_nRow, m_pBirthday->value());
	pAddressBookDB->SetCategory(m_nRow,
				    AddressBookCategoryDB::
				    GetAddressBookCategoryDB()->
				    GetCategoryID(m_pCategory->value()));
	pAddressBookDB->SetCity(m_nRow, m_pCity->value());
	pAddressBookDB->SetCompany(m_nRow, m_pCompany->value());
	pAddressBookDB->SetCountry(m_nRow, m_pCountry->value());
	pAddressBookDB->SetFirstName(m_nRow, m_pFirstName->value());
	pAddressBookDB->SetLastName(m_nRow, m_pLastName->value());
	pAddressBookDB->SetPostalCode(m_nRow, m_pPostalCode->value());
	pAddressBookDB->SetRegion(m_nRow, m_pRegion->value());
	pAddressBookDB->SetTitle(m_nRow, m_pTitle->value());

	// Determine the show flag
	for (i = 0; i < 7; ++i) {
	    if (m_pRadioButton[i]->value() == 1) {
		pAddressBookDB->SetShowFlag(m_nRow, i);
	    }
	}

	// Change the info fields
	for (i = 0; i < 7; ++i) {
	    pAddressBookDB->SetInfoID(m_nRow, i, m_pInfoChoice[i]->value());
	    pAddressBookDB->SetInfo(m_nRow, i, m_pInfo[i]->value());
	}

	// Change the custom fields
	for (i = 0; i < 4; ++i) {
	    pAddressBookDB->SetCustom(m_nRow, i, m_pCustom[i]->value());
	}

	// Save changes to the note, (AddressBookDB will save the note to disk)
	pAddressBookDB->SetNote(m_nRow, m_pNoteEditor->GetNote());

	// Save these changes
	pAddressBookDB->Save();

	// Save the record number for later
	m_nRecno = pAddressBookDB->GetRecno(m_nRow);
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Fill an Info choice menu with selections                     //
//--------------------------------------------------------------//
void
AddressBookDlg::FillInfoChoice(Fl_Choice * pChoice, int nIndex)
{
    int i;
    int nMax = AddressBookDB::GetInfoNameCount() + 1;

    // Create the menu
    m_pTranslatedMenu[nIndex] = new Fl_Menu_Item[nMax];
    memset(m_pTranslatedMenu[nIndex], 0, nMax * sizeof(Fl_Menu_Item));
    for (i = 0; i < nMax - 1; ++i) {
	// Use strdup so that FreeTranslatedMenu will work correctly
	m_pTranslatedMenu[nIndex][i].text =
	    strdup(AddressBookDB::GetInfoName(i).c_str());
    }

    // Set the menu
    pChoice->menu(m_pTranslatedMenu[nIndex]);
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
AddressBookDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_ADDRESS_BOOK_DLG);
}

--- NEW FILE: AddressBook.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Center of the window for the Address Book display            //
//--------------------------------------------------------------//
#ifndef ADDRESSBOOK_H_

#define ADDRESSBOOK_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <vector>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Menu_Item.H>
#include "AddressBookDetails.h"
#include "AddressBookList.h"
#include "InputNotify.h"
#include "Messages.h"
using namespace std;
class AddressBook:public Fl_Group
{
  public:AddressBook(Fl_Widget * pParent);
    // Default Constructor
    ~AddressBook();		// Destructor
    inline bool CanPaste() const	// Is there a row that can be pasted
    {
	return (m_vCopyString.size() > 0);
    }
    int Copy(int nRow);		// Copy a row to m_strCopyString
    int Cut(int nRow);		// Cut a row to m_strCopyString
    void Delete(int nRow);	// Delete an address book line
    inline void DisplayRow(int nRow)	// Display a particular row from the Address Book List
    {
	m_pAddressBookDetails->DisplayRow(nRow);
    }
    void Edit(int nRow);	// Edit an address book line
    void EditNew();		// Insertion of a new address book row has been requested
    int Message(PixilDTMessage nMessage,	// Notification from the parent widget
		int nInfo);
    int Paste();		// Paste the most recently cut/copied row
  private:AddressBookDetails * m_pAddressBookDetails;
    // The details portion of the display
    AddressBookList *m_pAddressBookList;	// The list portion of the display
    bool m_bUndoCut;		// Can a cut be undone
    bool m_bUndoPaste;		// Can a paste be undone
    Fl_Box *m_pTitle;		// Label box
    Fl_Button *m_pEditButton;	// Edit button
    Fl_Button *m_pListByButton;	// List By button
    Fl_Button *m_pNewButton;	// New button
    Fl_Choice *m_pCategory;	// Category choice
    Fl_Menu_Item *m_pCategoryMenu;	// Category choice menu
    InputNotify *m_pSearch;	// Search string
    int m_nLastPaste;		// Last row pasted
    vector < string > m_vCopyString;	// Most recently cut/copied row
    static void CategorySelected(Fl_Widget * pWidget,	// Category filtering has been changed
				 void *pUserData);
    static void EditButton(Fl_Widget * pWidget,	// Callback for the Edit button
			   void *pUserData);
    inline void Filter(int nCategory)	// Filter rows based on category
    {
	m_bUndoPaste = false;	// Paste is done by row number and rows may be re-ordered
	m_pAddressBookList->Filter(nCategory);
    }
    void FixDeletedCategory(int nCategory);	// Change any line for a deleted category back to Unfiled
    static void ListByButton(Fl_Widget * pWidget,	// Callback for the List By button
			     void *pUserData);
    inline static void NewButton(Fl_Widget * pWidget,	// Callback for the New button
				 void *pUserData)
    {
	((AddressBook *) (pWidget->parent()))->EditNew();
    }
    void ResetCategoryChoice();	// Reset the category choice after a category deletion
    static void SearchEntered(Fl_Widget * pWidget,	// Search string has been entered
			      void *pUserData);
    void ShowListByDialog();	// Show the List By dialog
    int Undo();			// Undo the most recent cut/paste
  public:void Refresh()
    {
	m_pAddressBookList->Refresh();
    }
};


#endif /*  */

--- NEW FILE: ScheduleContainer.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Schedule Container widget                                    //
//--------------------------------------------------------------//
#ifndef SCHEDULECONTAINER_H_

#define SCHEDULECONTAINER_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Scroll.H>
class ScheduleDay;

#include "ScheduleDay.h"
#include "ScheduleHours.h"

#include "FLTKUtil.h"
class ScheduleContainer:public Fl_Scroll
{
  public:ScheduleContainer(int nX,
		      // Constructor
		      int nY, int nWidth, int nHeight, int nDayCount);
     ~ScheduleContainer();	// Destructor
    void Delete(int nRow,	// Process a request to delete an appointment
		time_t nDate);
    void Edit(int nRow,		// Process a request to edit an appointment
	      time_t nDate);
    void EditNew(time_t nDate);	// Process a request to add a new appointment
    inline int GetContainerWidth() const	// Get the width of this widget not counting the hours and scrollbar
    {
	return (w() - m_nHourWidth - scrollbar.w());
    }
    inline int GetHoursWidth() const	// Get the width of the hours widget
    {
	return (m_nHourWidth);
    }
    inline int GetSelectedItem() const	// Get the last selected item
    {
	return (m_nSelectedRow);
    }
    void Refresh(time_t nDate);	// Refresh all displays within this container
    void resize(int nX,		// From Fl_Widget/Fl_Scroll - virtual resize method
		int nY, int nWidth, int nHeight);
    inline void SetSelectedItem(int nRow)	// Notification that an item has been selected
    {
	m_nSelectedRow = nRow;
    }
  private:  Fl_Group * m_pResizeGroup;
    // Contains all ScheduleDay objects
    int m_nDayCount;		// Count of days shown here
    int m_nHourHeight;		// Height of an hour in the display
    int m_nHourWidth;		// Width of an hour in the display
    int m_nSelectedRow;		// The selected row from child ScheduleDay/ScheduleEvent widgets
    time_t m_nDate;		// Date currently being displayed
    ScheduleDay **m_ppDay;	// Schedule days for this widget
    ScheduleHours *m_pHour;	// The hours on the left of the container
};


#endif /*  */

--- NEW FILE: ToDoListShowDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Address Book Dialog.                                         //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_ask.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Return_Button.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "Messages.h"
#include "Options.h"
#include "PixilDT.h"
#include "ToDoListShowDlg.h"

#include "VCMemoryLeak.h"


#define DLG_CHOICE_WIDTH 190
#define DLG_HEIGHT       (12*DLG_BORDER+7*DLG_BUTTON_HEIGHT)
#define DLG_WIDTH        400


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
ToDoListShowDlg::ToDoListShowDlg(Fl_Widget * pParent)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Show Options"))
{
    Fl_Box *pBox;

    // Create the dialog widgets
    // Create the sort order widget
    pBox = new Fl_Box(DLG_BORDER,
		      DLG_BORDER,
		      w() - 4 * DLG_BORDER - DLG_CHOICE_WIDTH -
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, _("Sort by:"));
    pBox->
	align(FL_ALIGN_LEFT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    CreateOrderWidget(w() - 2 * DLG_BORDER - DLG_BUTTON_WIDTH -
		      DLG_CHOICE_WIDTH, DLG_BORDER, DLG_CHOICE_WIDTH,
		      DLG_BUTTON_HEIGHT);

    // Create the buttons used for selections
    pBox = new Fl_Box(DLG_BORDER,
		      2 * DLG_BORDER + DLG_BUTTON_HEIGHT,
		      w() - 3 * DLG_BORDER - DLG_BUTTON_WIDTH,
		      h() - 3 * DLG_BORDER - DLG_BUTTON_HEIGHT);
    pBox->box(FL_EMBOSSED_FRAME);
    m_pCompletedButton = new Fl_Check_Button(3 * DLG_BORDER,
					     4 * DLG_BORDER +
					     DLG_BUTTON_HEIGHT,
					     w() - 5 * DLG_BORDER -
					     DLG_BUTTON_WIDTH,
					     DLG_BUTTON_HEIGHT,
					     _("Show &Completed Items"));
    m_pCompletedButton->down_box(FL_ROUND_DOWN_BOX);
    m_pCompletedButton->value(Options::GetToDoShowCompleted() ==
			      true ? 1 : 0);
    m_pDueButton =
	new Fl_Check_Button(3 * DLG_BORDER,
			    5 * DLG_BORDER + 2 * DLG_BUTTON_HEIGHT,
			    w() - 5 * DLG_BORDER - DLG_BUTTON_WIDTH,
			    DLG_BUTTON_HEIGHT, _("Show Only Due &Items"));
    m_pDueButton->down_box(FL_ROUND_DOWN_BOX);
    m_pDueButton->value(Options::GetToDoShowOnlyDue() == true ? 1 : 0);
    m_pDueDateButton = new Fl_Check_Button(3 * DLG_BORDER,
					   7 * DLG_BORDER +
					   4 * DLG_BUTTON_HEIGHT,
					   w() - 5 * DLG_BORDER -
					   DLG_BUTTON_WIDTH,
					   DLG_BUTTON_HEIGHT,
					   _("Show &Due Dates"));
    m_pDueDateButton->down_box(FL_ROUND_DOWN_BOX);
    m_pDueDateButton->value(Options::GetToDoShowDueDate() == true ? 1 : 0);
    m_pPriorityButton = new Fl_Check_Button(3 * DLG_BORDER,
					    8 * DLG_BORDER +
					    5 * DLG_BUTTON_HEIGHT,
					    w() - 5 * DLG_BORDER -
					    DLG_BUTTON_WIDTH,
					    DLG_BUTTON_HEIGHT,
					    _("Show &Priorities"));
    m_pPriorityButton->down_box(FL_ROUND_DOWN_BOX);
    m_pPriorityButton->value(Options::GetToDoShowPriority() == true ? 1 : 0);
    m_pCategoryButton = new Fl_Check_Button(3 * DLG_BORDER,
					    9 * DLG_BORDER +
					    6 * DLG_BUTTON_HEIGHT,
					    w() - 5 * DLG_BORDER -
					    DLG_BUTTON_WIDTH,
					    DLG_BUTTON_HEIGHT,
					    _("Show &Categories"));
    m_pCategoryButton->down_box(FL_ROUND_DOWN_BOX);
    m_pCategoryButton->value(Options::GetToDoShowCategory() == true ? 1 : 0);

    // Create the buttons
    m_pOKButton = new Fl_Return_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				       DLG_BORDER,
				       DLG_BUTTON_WIDTH,
				       DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton = new Fl_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				    2 * DLG_BORDER + DLG_BUTTON_HEIGHT,
				    DLG_BUTTON_WIDTH,
				    DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				  3 * DLG_BORDER + 2 * DLG_BUTTON_HEIGHT,
				  DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);

    end();

    // The DoModal method will call show on this window
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
ToDoListShowDlg::~ToDoListShowDlg()
{
    FreeTranslatedMenu(m_pSortMenu);
}


//--------------------------------------------------------------//
// Create the sort order widget                                 //
//--------------------------------------------------------------//
void
ToDoListShowDlg::CreateOrderWidget(int nX, int nY, int nWidth, int nHeight)
{
    static const char *pszMenuText[4] = {
	N_("Priority, Due Date"),
	N_("Due Date, Priority"),
	N_("Category, Due Date"),
	N_("Category, Priority"),
    };
    int i;
    int nMax = sizeof(pszMenuText) / sizeof(char *);

    // Create the widget
    m_pSortChoice = new Fl_Choice(nX, nY, nWidth, nHeight);

    // Create the menu
    m_pSortMenu = new Fl_Menu_Item[nMax + 1];
    memset(m_pSortMenu, 0, (nMax + 1) * sizeof(Fl_Menu_Item));

    // Add the categories to the menu
    for (i = 0; i < nMax; ++i) {
	// Use strdup so that FreeTranslatedMenu will work correctly
	m_pSortMenu[i].text = strdup(_(pszMenuText[i]));
    }

    // Set the menu into the choice
    m_pSortChoice->menu(m_pSortMenu);

    // Set the initial value
    m_pSortChoice->value(Options::GetToDoSort());
}


//--------------------------------------------------------------//
// Run the modal dialog                                         //
//--------------------------------------------------------------//
int
ToDoListShowDlg::DoModal()
{
    int nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

    if (nReturn == 1) {
	// OK button was pressed, update the show options
	Options::SetToDoShowCompleted(m_pCompletedButton->value() ==
				      1 ? true : false);
	Options::SetToDoShowOnlyDue(m_pDueButton->value() ==
				    1 ? true : false);
	Options::SetToDoShowDueDate(m_pDueDateButton->value() ==
				    1 ? true : false);
	Options::SetToDoShowPriority(m_pPriorityButton->value() ==
				     1 ? true : false);
	Options::SetToDoShowCategory(m_pCategoryButton->value() ==
				     1 ? true : false);
	Options::SetToDoSort(m_pSortChoice->value());
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
ToDoListShowDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_TODO_SHOW_DLG);
}

--- NEW FILE: InfoGroup.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Center information for the main window.                      //
//--------------------------------------------------------------//
#include <cstdio>
#include "InfoGroup.h"
#include "Messages.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Default constructor                                          //
//--------------------------------------------------------------//
InfoGroup::InfoGroup(int x, int y, int width, int height)
    :
Fl_Group(x, y, width, height)
{
    // Create each of the 4 groups to be displayed in this window
    m_pAddressBook = new AddressBook(this);
    m_pNotes = new Notes(this);
    m_pScheduler = new Scheduler(this);
    m_pToDoList = new ToDoList(this);
    end();

    // Set up a lowered box
    box(FL_DOWN_BOX);

    // Set that this is resizable
    resizable(this);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
InfoGroup::~InfoGroup()
{
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
InfoGroup::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case ADDRESS_BOOK_CHANGED:
	m_pAddressBook->Message(nMessage, 0);
	m_pScheduler->Message(nMessage, 0);
	break;

    case NOTES_CHANGED:
	m_pNotes->Message(nMessage, 0);
	break;

    case SCHEDULER_CHANGED:
	m_pScheduler->Message(nMessage, 0);
	break;

    case TODO_LIST_CHANGED:
	m_pScheduler->Message(nMessage, 0);
	m_pToDoList->Message(nMessage, 0);
	break;

    case ADDRESS_BOOK_REQUESTED:
    case NOTES_REQUESTED:
    case SCHEDULER_REQUESTED:
    case TODO_LIST_REQUESTED:
	m_pAddressBook->Message(nMessage, 0);
	m_pNotes->Message(nMessage, 0);
	m_pScheduler->Message(nMessage, 0);
	m_pToDoList->Message(nMessage, 0);
	ShowInfo(nMessage);
	break;

    case ADDRESS_BOOK_CATEGORY_ADDED:
    case ADDRESS_BOOK_CATEGORY_DELETED:
    case ADDRESS_BOOK_CATEGORY_RENAMED:
    case ADDRESS_BOOK_DELETE:
    case ADDRESS_BOOK_GOTO:
    case ADDRESS_BOOK_NEW:
    case ADDRESS_BOOK_PRINT:
    case SHOW_LIST_BY:
	m_pAddressBook->Message(nMessage, nInfo);
	break;

    case NOTES_CATEGORY_ADDED:
    case NOTES_CATEGORY_DELETED:
    case NOTES_CATEGORY_RENAMED:
    case NOTES_DELETE:
    case NOTES_GOTO:
    case NOTES_NEW:
    case NOTES_PRINT:
	m_pNotes->Message(nMessage, nInfo);
	break;

    case BEGIN_WEEK_CHANGED:	// The beginning day of week has been changed
    case SCHEDULER_CATEGORY_ADDED:
    case SCHEDULER_CATEGORY_DELETED:
    case SCHEDULER_CATEGORY_RENAMED:
    case SCHEDULER_DELETE:
    case SCHEDULER_GOTO:
    case SCHEDULER_NEW:
    case SCHEDULER_PRINT:
	m_pScheduler->Message(nMessage, nInfo);
	break;

    case SHOW_TODO_OPTIONS:
    case TODO_LIST_CATEGORY_ADDED:
    case TODO_LIST_CATEGORY_DELETED:
    case TODO_LIST_CATEGORY_RENAMED:
    case TODO_LIST_DELETE:
    case TODO_LIST_GOTO:
    case TODO_LIST_NEW:
    case TODO_LIST_PRINT:
	m_pToDoList->Message(nMessage, nInfo);
	break;

    case SELECTION_CHANGING:	// 0 return means to refuse the change
	nReturn = m_pAddressBook->Message(nMessage, nInfo);
	nReturn &= m_pNotes->Message(nMessage, nInfo);
	nReturn &= m_pScheduler->Message(nMessage, nInfo);
	nReturn &= m_pToDoList->Message(nMessage, nInfo);
	break;

    case APPLICATION_CLOSING:
	m_pAddressBook->Message(nMessage, 0);
	m_pNotes->Message(nMessage, 0);
	m_pScheduler->Message(nMessage, 0);
	m_pToDoList->Message(nMessage, 0);
	break;

    case EDIT_COPY:		// Pass these on to only the active page
    case EDIT_CUT:
    case EDIT_PASTE:
    case EDIT_UNDO:
    case EDIT_COPY_AVAILABLE:
    case EDIT_CUT_AVAILABLE:
    case EDIT_PASTE_AVAILABLE:
    case EDIT_UNDO_AVAILABLE:
	switch (m_nCurrentPage) {
	case ADDRESS_BOOK_REQUESTED:
	    nReturn = m_pAddressBook->Message(nMessage, nInfo);
	    break;

	case NOTES_REQUESTED:
	    nReturn = m_pNotes->Message(nMessage, nInfo);
	    break;

	case SCHEDULER_REQUESTED:
	    nReturn = m_pScheduler->Message(nMessage, nInfo);
	    break;

	case TODO_LIST_REQUESTED:
	    nReturn = m_pToDoList->Message(nMessage, nInfo);
	}
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}

void
InfoGroup::Refresh()
{
    NxDbAccess::RefreshAll();
    m_pToDoList->Refresh();
    m_pAddressBook->Refresh();
    m_pScheduler->Refresh();
    m_pNotes->Refresh();
}

//--------------------------------------------------------------//
// Show a particular set of information                         //
//--------------------------------------------------------------//
void
InfoGroup::ShowInfo(PixilDTMessage nMessage)
{
    // Hide or show the correct group
    if (nMessage == ADDRESS_BOOK_REQUESTED) {
	m_pAddressBook->show();
    } else {
	m_pAddressBook->hide();
    }

    if (nMessage == NOTES_REQUESTED) {
	m_pNotes->show();
    } else {
	m_pNotes->hide();
    }

    if (nMessage == SCHEDULER_REQUESTED) {
	m_pScheduler->show();
    } else {
	m_pScheduler->hide();
    }

    if (nMessage == TODO_LIST_REQUESTED) {
	m_pToDoList->show();
    } else {
	m_pToDoList->hide();
    }

    m_nCurrentPage = nMessage;
}

--- NEW FILE: SchedulerRepeatDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Dialog for adding/updating Scheduler appointments.           //
//--------------------------------------------------------------//
#include "config.h"
#include <cstdlib>
#include <FL/Fl.H>
#include <FL/fl_ask.H>
#include <FL/Fl_Repeat_Button.H>
#include <FL/Fl_Return_Button.H>
#include "DatePickerDlg.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "Images.h"
#include "Options.h"
#include "PixilDT.h"
#include "SchedulerRepeatDlg.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT         200
#define DLG_WIDTH          350
#define PAGE_INDENT        100
#define RADIO_BUTTON_WIDTH 100


//--------------------------------------------------------------//
// Constructor, nRow is the row number in the Scheduler         //
// database as currently sorted or a -1 if this is to be a new  //
// row.                                                         //
//--------------------------------------------------------------//
SchedulerRepeatDlg::SchedulerRepeatDlg(const SchedulerRepeatData *
				       pSchedulerRepeatData,
				       Fl_Widget * pParent)
    :
Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Change Repeat"))
{
    int i;
    int nHeight;
    int nX;
    int nY;
    int nWidth;

    // Copy the Scheduler repetition settings
    m_pSchedulerRepeatData = new SchedulerRepeatData(*pSchedulerRepeatData);

    // Create the dialog widgets

    // Create the 5 radio buttons
    for (i = 0; i < 5; ++i) {
	m_strRadioLabel[i] =
	    SchedulerDB::GetRepeatTypeString(i == 0 ? 0 : (1 << (i - 1)));
	m_pRadioButton[i] =
	    new Fl_Check_Button(DLG_BORDER,
				DLG_BORDER + i * (DLG_BORDER +
						  DLG_INPUT_HEIGHT),
				DLG_RADIO_SIZE, DLG_INPUT_HEIGHT,
				m_strRadioLabel[i].c_str());
	m_pRadioButton[i]->type(FL_RADIO_BUTTON);
	m_pRadioButton[i]->down_box(FL_ROUND_DOWN_BOX);
	m_pRadioButton[i]->user_data((void *) i);
	m_pRadioButton[i]->
	    value((i == m_pSchedulerRepeatData->GetRepeatIndex())? 1 : 0);
	m_pRadioButton[i]->callback(OnRadioButton);
    }

    // Create each of the 5 groups corresponding to each of the 5 radio buttons
    nX = DLG_BORDER + RADIO_BUTTON_WIDTH;
    nY = DLG_BORDER;
    nWidth = w() - 2 * DLG_BORDER - RADIO_BUTTON_WIDTH;
    nHeight = h() - 4 * DLG_BORDER - DLG_BUTTON_HEIGHT;
    CreatePage1(nX, nY, nWidth, nHeight);
    CreatePage2(nX, nY, nWidth, nHeight);
    CreatePage3(nX, nY, nWidth, nHeight);
    CreatePage4(nX, nY, nWidth, nHeight);
    CreatePage5(nX, nY, nWidth, nHeight);

    // Show the correct page
    OnRadioButton(m_pRadioButton[m_pSchedulerRepeatData->GetRepeatIndex()],
		  (void *) m_pSchedulerRepeatData->GetRepeatIndex());

    // Create the buttons
    m_pOKButton =
	new Fl_Return_Button(w() - 3 * DLG_BUTTON_WIDTH - 3 * DLG_BORDER,
			     h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
			     DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton =
	new Fl_Button(w() - 2 * DLG_BUTTON_WIDTH - 2 * DLG_BORDER,
		      h() - DLG_BORDER - DLG_BUTTON_HEIGHT, DLG_BUTTON_WIDTH,
		      DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - DLG_BUTTON_WIDTH - DLG_BORDER,
				  h() - DLG_BORDER - DLG_BUTTON_HEIGHT,
				  DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);

    end();

    // Get the initial values for the data

    // The DoModal method will call show on this window
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
SchedulerRepeatDlg::~SchedulerRepeatDlg()
{
    FreeTranslatedMenu(m_pMonthMenu);
    delete m_pDayCalendarPixmap;
    delete m_pMonthCalendarPixmap;
    delete m_pWeekCalendarPixmap;
    delete m_pYearCalendarPixmap;
    delete m_pSchedulerRepeatData;
}


//--------------------------------------------------------------//
// Create an end date set of widgets.                           //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::CreateEndDate(int nIndex)
{
    Fl_Button *pButton;
    Fl_Input **ppInput;
    Fl_Pixmap **ppPixmap;

    // Set up for the page being created
    switch (nIndex) {
    case 1:			// Daily page
	ppInput = &m_pDayEnd;
	ppPixmap = &m_pDayCalendarPixmap;
	break;

    case 2:			// Weekly page
	ppInput = &m_pWeekEnd;
	ppPixmap = &m_pWeekCalendarPixmap;
	break;

    case 3:			// Monthly page
	ppInput = &m_pMonthEnd;
	ppPixmap = &m_pMonthCalendarPixmap;
	break;

    case 4:			// Yearly page
	ppInput = &m_pYearEnd;
	ppPixmap = &m_pYearCalendarPixmap;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Wrong page type
#endif
	;
    }

    *ppInput = new Fl_Input(m_pPage[nIndex]->x() + PAGE_INDENT,
			    m_pPage[nIndex]->y() + 2 * DLG_BORDER +
			    DLG_INPUT_HEIGHT,
			    m_pPage[nIndex]->w() - PAGE_INDENT -
			    IMAGE_BUTTON_WIDTH - 2 * DLG_BORDER,
			    DLG_INPUT_HEIGHT, _("End on:"));
    (*ppInput)->value(::FormatDate(m_pSchedulerRepeatData->GetEndDate()).
		      c_str());
    pButton =
	new Fl_Button(m_pPage[nIndex]->x() + m_pPage[nIndex]->w() -
		      DLG_BORDER - IMAGE_BUTTON_WIDTH,
		      m_pPage[nIndex]->y() + 2 * DLG_BORDER +
		      DLG_INPUT_HEIGHT, IMAGE_BUTTON_WIDTH,
		      IMAGE_BUTTON_HEIGHT);
    pButton->user_data((void *) nIndex);
    pButton->callback(OnDateButton);
    *ppPixmap = Images::GetCalendarIcon();
    (*ppPixmap)->label(pButton);
}


//--------------------------------------------------------------//
// Create the first "page".                                     //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::CreatePage1(int nX, int nY, int nWidth, int nHeight)
{
    Fl_Box *pBox;

    // Create the containing group
    m_pPage[0] = new Fl_Group(nX, nY, nWidth, nHeight);

    // Just some verbiage about selecting some repeat type
    pBox = new Fl_Box(nX + DLG_BORDER,
		      nY + DLG_BORDER,
		      nWidth - 2 * DLG_BORDER, nHeight - 2 * DLG_BORDER);
    pBox->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
    pBox->
	label(_
	      ("Click one of the buttons to the left to select a repeat interval"));

    // Finish the group
    m_pPage[0]->end();
}


//--------------------------------------------------------------//
// Create the second "page".                                    //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::CreatePage2(int nX, int nY, int nWidth, int nHeight)
{
    // Create the containing group
    m_pPage[1] = new Fl_Group(nX, nY, nWidth, nHeight);

    // Create what looks like a spin control
    CreateSpinButton(1);

    // Create the end date widgets
    CreateEndDate(1);

    // Finish the group
    m_pPage[1]->end();
}


//--------------------------------------------------------------//
// Create the third "page".                                     //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::CreatePage3(int nX, int nY, int nWidth, int nHeight)
{
    Fl_Box *pBox;
    int i;
    int nButtonWidth;
    int nFontSize = (4 * labelsize()) / 5;
    int nTotalValue;
    int nValue;
    int nWeekBegin = Options::GetWeekBegins();

    // Create the containing group
    m_pPage[2] = new Fl_Group(nX, nY, nWidth, nHeight);

    // Create what looks like a spin control
    CreateSpinButton(2);

    // Create the end date widgets
    CreateEndDate(2);

    // Create the day of week label
    pBox = new Fl_Box(m_pPage[2]->x() + DLG_BORDER,
		      m_pPage[2]->y() + 3 * DLG_BORDER + 2 * DLG_INPUT_HEIGHT,
		      PAGE_INDENT - 2 * DLG_BORDER,
		      DLG_INPUT_HEIGHT, _("Day(s) of Week:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);

    // Create the day of week widgets
    m_pWeekDays = new Fl_Group(nX + PAGE_INDENT,
			       nY + 3 * DLG_BORDER + 2 * DLG_INPUT_HEIGHT,
			       nWidth - PAGE_INDENT - DLG_BORDER,
			       DLG_INPUT_HEIGHT);
    m_pWeekDays->box(FL_DOWN_BOX);
    m_pWeekDays->color(FL_WHITE);
    nButtonWidth = m_pWeekDays->w() / 7;
    nTotalValue = 0;
    for (i = 0; i < 7; ++i) {
	m_strWeekdayLabel[i] =
	    string(::GetDayOfWeek((i + nWeekBegin) % 7)).substr(0, 1);
	m_pWeekDayButton[i] =
	    new Fl_Button(m_pWeekDays->x() + i * nButtonWidth,
			  m_pWeekDays->y(), nButtonWidth, DLG_INPUT_HEIGHT,
			  m_strWeekdayLabel[i].c_str());
	m_pWeekDayButton[i]->box(FL_BORDER_BOX);
	m_pWeekDayButton[i]->labelsize(nFontSize);
	m_pWeekDayButton[i]->labelfont(FL_HELVETICA_BOLD);
	m_pWeekDayButton[i]->type(FL_TOGGLE_BUTTON);
	nValue =
	    (m_pSchedulerRepeatData->
	     IsWeekDaySelected((i + nWeekBegin) % 7) == true ? 1 : 0);
	m_pWeekDayButton[i]->value(nValue);
	nTotalValue += nValue;
	m_pWeekDayButton[i]->user_data((void *) ((i + nWeekBegin) % 7));
	OnWeekDay(m_pWeekDayButton[i], m_pWeekDayButton[i]->user_data());
	m_pWeekDayButton[i]->callback(OnWeekDay);
    }

    // Pick the current day of week if none were already selected
    if (nTotalValue == 0) {
	i =::GetDow(m_pSchedulerRepeatData->GetStartTime());
	i = ((i + 7 - nWeekBegin) % 7);
	m_pWeekDayButton[i]->value(1);
	OnWeekDay(m_pWeekDayButton[i], m_pWeekDayButton[i]->user_data());
    }
    // End the page
    m_pWeekDays->end();

    // Finish the window
    m_pPage[2]->end();
}


//--------------------------------------------------------------//
// Create the fourth "page".                                    //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::CreatePage4(int nX, int nY, int nWidth, int nHeight)
{
    static const Fl_Menu_Item menuChoice[] = {
	{N_("Date")},
	{N_("Day")},
	{NULL},
    };

    // Create the containing group
    m_pPage[3] = new Fl_Group(nX, nY, nWidth, nHeight);

    // Create what looks like a spin control
    CreateSpinButton(3);

    // Create the end date widgets
    CreateEndDate(3);

    // Create the "By" choice
    m_pMonthBy = new Fl_Choice(nX + PAGE_INDENT,
			       nY + 2 * DLG_BORDER + 2 * DLG_INPUT_HEIGHT,
			       nWidth - PAGE_INDENT - DLG_BORDER,
			       DLG_BUTTON_HEIGHT, _("By:"));
    m_pMonthMenu = TranslateMenuItems(menuChoice);
    m_pMonthBy->menu(m_pMonthMenu);
    m_pMonthBy->value(m_pSchedulerRepeatData->GetRepeatMonthByDay()? 1 : 0);

    // Finish the group
    m_pPage[3]->end();
}


//--------------------------------------------------------------//
// Create the fifth "page".                                     //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::CreatePage5(int nX, int nY, int nWidth, int nHeight)
{
    // Create the containing group
    m_pPage[4] = new Fl_Group(nX, nY, nWidth, nHeight);

    // Create what looks like a spin control
    CreateSpinButton(4);

    // Create the end date widgets
    CreateEndDate(4);

    // Finish the group
    m_pPage[4]->end();
}


//--------------------------------------------------------------//
// Create a spin button                                         //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::CreateSpinButton(int nIndex)
{
    const char *pszSpinLabel;
    int nLabelHeight;
    int nLabelWidth;
    SpinInput **ppEvery;

    // Set up for the page being created
    switch (nIndex) {
    case 1:			// Daily page
	pszSpinLabel = _("Days");
	ppEvery = &m_pDayEvery;
	break;

    case 2:			// Weekly page
	pszSpinLabel = _("Weeks");
	ppEvery = &m_pWeekEvery;
	break;

    case 3:			// Monthly page
	pszSpinLabel = _("Months");
	ppEvery = &m_pMonthEvery;
	break;

    case 4:			// Yearly page
	pszSpinLabel = _("Years");
	ppEvery = &m_pYearEvery;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Wrong page type
#endif
	;
    }

    // Get the width of a "0000" constant in the current font
    fl_font(labelfont(), labelsize());
    fl_measure("0000", nLabelWidth, nLabelHeight);
    nLabelWidth += 2 * Fl::box_dw(FL_DOWN_BOX);

    // Create what looks like a spin control with some surrounding text
    *ppEvery = new SpinInput(m_pPage[nIndex]->x() + PAGE_INDENT,
			     m_pPage[nIndex]->y() + DLG_BORDER,
			     nLabelWidth + IMAGE_BUTTON_WIDTH,
			     DLG_INPUT_HEIGHT, _("Every:"), 3, 1, 999);
    new Fl_Box(m_pPage[nIndex]->x() + PAGE_INDENT + nLabelWidth +
	       IMAGE_BUTTON_WIDTH + DLG_BORDER,
	       m_pPage[nIndex]->y() + DLG_BORDER,
	       m_pPage[nIndex]->w() - PAGE_INDENT - nLabelWidth -
	       IMAGE_BUTTON_WIDTH - 2 * DLG_BORDER, DLG_INPUT_HEIGHT,
	       pszSpinLabel);

    // Set the initial value of the "Every" input widget
    if (nIndex == m_pSchedulerRepeatData->GetRepeatIndex()) {
	// Set the value from the repeat settings
	(*ppEvery)->value(m_pSchedulerRepeatData->GetRepeatEvery());
    } else {
	// Just default to 1 or every time unit
	(*ppEvery)->value(1);
    }
}


//--------------------------------------------------------------//
// Run the modal dialog                                         //
//--------------------------------------------------------------//
int
SchedulerRepeatDlg::DoModal()
{
    bool bGood = false;
    int nResult;
    int nReturn = 1;
    int nWeekBegin = Options::GetWeekBegins();
    time_t nDate;

    while (nReturn == 1 && bGood == false) {
	// Go run the dialog
	nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

	// Was the OK button pressed ?
	if (nReturn == 1) {
	    // Validate all fields
	    bGood = true;
	    if (m_pRadioButton[0]->value() == 1) {
		// No repetitions requested
		m_pSchedulerRepeatData->SetNoRepetition();
	    } else if (m_pRadioButton[1]->value() == 1) {
		// Daily repetitions requested

		// Validate the end date
		if ((nResult =::ValidateDate(m_pDayEnd->value(), nDate)) < 0) {
		    fl_alert(_
			     ("The Daily Repeat End Date is not a valid date:\n\n%s"),::
			     GetDateError(nResult));
		    bGood = false;
		} else if (nDate >= 24 * 60 * 60
			   && nDate < ::NormalizeDate(m_pSchedulerRepeatData->
						     GetStartTime())) {
		    fl_alert(_
			     ("The Daily Repeat End Date is prior to the event start date:\n\n%s"),::
			     GetDateError(nResult));
		    bGood = false;
		} else {
		    // Save the data
		    m_pSchedulerRepeatData->SetDailyRepetition(m_pDayEvery->
							       value(),
							       nDate);
		}
	    } else if (m_pRadioButton[2]->value() == 1) {
		// Weekly repetitions requested

		// Validate the end date
		if ((nResult =::ValidateDate(m_pWeekEnd->value(), nDate)) < 0) {
		    fl_alert(_
			     ("The Weekly Repeat End Date is not a valid date:\n\n%s"),::
			     GetDateError(nResult));
		    bGood = false;
		} else if (nDate >= 24 * 60 * 60
			   && nDate < ::NormalizeDate(m_pSchedulerRepeatData->
						     GetStartTime())) {
		    fl_alert(_
			     ("The Weekly Repeat End Date is prior to the event start date:\n\n%s"),::
			     GetDateError(nResult));
		    bGood = false;
		} else if (m_pWeekDayButton[0]->value() == 0
			   && m_pWeekDayButton[1]->value() == 0
			   && m_pWeekDayButton[2]->value() == 0
			   && m_pWeekDayButton[3]->value() == 0
			   && m_pWeekDayButton[4]->value() == 0
			   && m_pWeekDayButton[5]->value() == 0
			   && m_pWeekDayButton[6]->value() == 0) {
		    fl_alert(_("At least one day-of-week must be selected"));
		    bGood = false;
		} else {
		    // Save the data
		    m_pSchedulerRepeatData->SetWeeklyRepetition(m_pWeekEvery->
								value(),
								m_pWeekDayButton
								[(7 -
								  nWeekBegin)
								 %
								 7]->value(),
								m_pWeekDayButton
								[1 -
								 nWeekBegin]->
								value(),
								m_pWeekDayButton
								[2 -
								 nWeekBegin]->
								value(),
								m_pWeekDayButton
								[3 -
								 nWeekBegin]->
								value(),
								m_pWeekDayButton
								[4 -
								 nWeekBegin]->
								value(),
								m_pWeekDayButton
								[5 -
								 nWeekBegin]->
								value(),
								m_pWeekDayButton
								[6 -
								 nWeekBegin]->
								value(),
								nDate);
		}
	    } else if (m_pRadioButton[3]->value() == 1) {
		// Monthly repetitions requested

		// Validate the end date
		if ((nResult =::ValidateDate(m_pMonthEnd->value(), nDate)) <
		    0) {
		    fl_alert(_
			     ("The Monthly Repeat End Date is not a valid date:\n\n%s"),::
			     GetDateError(nResult));
		    bGood = false;
		} else if (nDate >= 24 * 60 * 60
			   && nDate < ::NormalizeDate(m_pSchedulerRepeatData->
						     GetStartTime())) {
		    fl_alert(_
			     ("The Monthly Repeat End Date is prior to the event start date:\n\n%s"),::
			     GetDateError(nResult));
		    bGood = false;
		} else {
		    // Save the data
		    m_pSchedulerRepeatData->
			SetMonthlyRepetition(m_pMonthEvery->value(),
					     m_pMonthBy->value(), nDate);
		}
	    } else		//if (m_pRadioButton[4]->value()==1)
	    {
		// Yearly repetitions requested

		// Validate the end date
		if ((nResult =::ValidateDate(m_pYearEnd->value(), nDate)) < 0) {
		    fl_alert(_
			     ("The Yearly Repeat End Date is not a valid date:\n\n%s"),::
			     GetDateError(nResult));
		    bGood = false;
		} else if (nDate >= 24 * 60 * 60
			   && nDate < ::NormalizeDate(m_pSchedulerRepeatData->
						     GetStartTime())) {
		    fl_alert(_
			     ("The Yearly Repeat End Date is prior to the event start date:\n\n%s"),::
			     GetDateError(nResult));
		    bGood = false;
		} else {
		    // Save the data
		    m_pSchedulerRepeatData->SetYearlyRepetition(m_pYearEvery->
								value(),
								nDate);
		}
	    }
	}
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// One of the date/calendar buttons was clicked (static         //
// callback).                                                   //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::OnDateButton(Fl_Widget * pWidget, void *pUserData)
{
    DatePickerDlg *pDlg;
    Fl_Input *pEnd;
    int nButton = reinterpret_cast < int >(pUserData);
    int nResult;
    SchedulerRepeatDlg *pThis =
	reinterpret_cast <
	SchedulerRepeatDlg * >(pWidget->parent()->parent());
    time_t nDate;

    // Increase the "Every" setting if not at the maximum
    switch (nButton) {
    case 1:			// Daily button
	pEnd = pThis->m_pDayEnd;
	break;

    case 2:			// Weekly button
	pEnd = pThis->m_pWeekEnd;
	break;

    case 3:			// Monthly button
	pEnd = pThis->m_pMonthEnd;
	break;

    case 4:			// Yearly button
	pEnd = pThis->m_pYearEnd;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Incorrect user_data on button
#endif
	pEnd = pThis->m_pDayEnd;
    }

    // Get the current end date
    nResult =::ValidateDate(pEnd->value(), nDate);
    if (nResult != 0 || nDate == 0) {
	// Bad date, use today + the type of repetition
	struct tm *pTm;

	nDate =::NormalizeDate(time(NULL));
	switch (nButton) {
	case 1:		// Daily repetition
	    nDate = AddDays(nDate, 1);
	    pTm = localtime(&nDate);
	    break;

	case 2:		// Weekly repetition
	    nDate = AddDays(nDate, 7);
	    pTm = localtime(&nDate);
	    break;

	case 3:		// Monthly repetition
	    pTm = localtime(&nDate);
	    switch (pTm->tm_mon) {
	    case 0:		// January
		if (pTm->tm_mday > 28) {
		    // Is this a leap year
		    if ((pTm->tm_year % 4) == 0) {
			pTm->tm_mday = 29;
		    } else {
			pTm->tm_mday = 28;
		    }
		}
		++pTm->tm_mon;
		break;

	    case 1:		// February
	    case 3:		// April
	    case 5:		// June
	    case 6:		// July
	    case 8:		// September
	    case 10:		// November
		++pTm->tm_mon;
		break;

	    case 2:		// March
	    case 4:		// May
	    case 7:		// August
	    case 9:		// October
		if (pTm->tm_mday == 31) {
		    pTm->tm_mday = 30;
		}
		++pTm->tm_mon;
		break;

	    case 11:		// December
		++pTm->tm_year;
		pTm->tm_mon = 0;
	    }
	    break;

	case 4:		// Monthly repetition
	    pTm = localtime(&nDate);
	    if (pTm->tm_mon == 1 && pTm->tm_mday == 29) {
		pTm->tm_mday = 28;
	    }
	    ++pTm->tm_year;
	}

	// Get the trial end date
	nDate = mktime(pTm);
    }
    // Do the date picker dialog
    pDlg =
	new DatePickerDlg(nDate, DatePicker::Daily,
			  PixilDT::GetApp()->GetMainWindow());
    if (pDlg->DoModal() == 1) {
	// Save the date
	pEnd->value(::FormatDate(pDlg->GetDate()).c_str());
    }
    // Clean up
    delete pDlg;

    // This seems to be needed here
    pThis->redraw();
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_SCHEDULER_REPEAT_DLG);
}


//--------------------------------------------------------------//
// One of the radio buttons was clicked (static callback).      //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::OnRadioButton(Fl_Widget * pWidget, void *pUserData)
{
    int i;
    int nButton = reinterpret_cast < int >(pUserData);
    SchedulerRepeatDlg *pThis =
	reinterpret_cast < SchedulerRepeatDlg * >(pWidget->parent());

    // Hide the pages that don't go with this button
    for (i = 0; i < 5; ++i) {
	if (i != nButton) {
	    pThis->m_pPage[i]->hide();
	}
    }

    // Show the page that correspnds to this button
    pThis->m_pPage[nButton]->show();
}


//--------------------------------------------------------------//
// One of the day-of-week buttons on the weekly page was        //
// clicked (static callback).                                   //
//--------------------------------------------------------------//
void
SchedulerRepeatDlg::OnWeekDay(Fl_Widget * pWidget, void *pUserData)
{
    Fl_Color nColor;
    Fl_Color nLabelColor;

    // Simply toggle the color of the button
    if (((Fl_Button *) pWidget)->value() == 1) {
	nColor = FL_SELECTION_COLOR;
	nLabelColor = FL_WHITE;
    } else {
	nColor = FL_GRAY;
	nLabelColor = FL_BLACK;
    }
    ((Fl_Button *) pWidget)->color(nColor);
    ((Fl_Button *) pWidget)->selection_color(nColor);
    ((Fl_Button *) pWidget)->labelcolor(nLabelColor);
    pWidget->redraw();
}

--- NEW FILE: InfoDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// "Info" database definition fields.                           //
//--------------------------------------------------------------//
#ifndef INFODB_H_

#define INFODB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include "NxDbAccess.h"

// Field References
#define INFOID   0
#define INFOTYPE 1
class InfoDB:public NxDbAccess
{
  public:InfoDB();		// Constructor
    ~InfoDB();			// Destructor
    static InfoDB *InfoDB::GetInfo();	// Get a pointer to this object
    inline string GetInfoType(int nRow) const	// Get the Info Type string
    {
	return (GetStringValue(nRow, INFOTYPE));
    }
    inline int GetInfoID(int nRow) const	// Get the recno column
    {
	return (GetIntValue(nRow, INFOID));
    }
    int Insert(int nInfoID);	// Insert a row and set its key id
    inline void SetInfoType(int nRow, const char *pszInfoType)	// Set the Info Type string
    {
	SetColumn(nRow, INFOTYPE, pszInfoType);
    }
  private:static const char *m_pszDefaultType[];
    // Initial rows
    static InfoDB *m_pThis;	// One and only address book object
    void Init();		// Initialize the database if empty
};


#endif /*  */

--- NEW FILE: PixilMainWnd.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
[...1129 lines suppressed...]
    //  return;
    char *pixil_bin = getenv("PIXIL_BIN");
    char *pixil_data = getenv("PIXIL_DATA");
    char cmd_line[4096];

    if (!pixil_bin || !pixil_data)
	return;

    sprintf(cmd_line, "%s/pull.sh", pixil_bin);

    int pid = fork();

    if (!pid) {
	execl(cmd_line, cmd_line, 0);
    } else {
	wait(NULL);
	g_MainWnd->m_pInfoGroup->Refresh();
    }

}

--- NEW FILE: CustomFieldDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Custom field name database.                                  //
//--------------------------------------------------------------//
#ifndef CUSTOMFIELDDB_H_

#define CUSTOMFIELDDB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include "NxDbAccess.h"

// Field References
#define CUSTOMID 0
#define CUSTOM 1

#define CUSTOM_NAME 10
class CustomFieldDB:public NxDbAccess
{
  public:CustomFieldDB();	// Constructor
    ~CustomFieldDB();		// Destructor
    inline string GetName(int nRow) const	// Get the custom field name
    {
	return (GetStringValue(nRow, CUSTOM));
    }
    static CustomFieldDB *GetCustomField();	// Get the singleton pointer
    inline int GetCustomID(int nRow) const	// Get the recno column
    {
	return (GetIntValue(nRow, CUSTOMID));
    }
    int Insert(int nID);	// Insert a row and set its key id
    inline void SetName(int nRow,	// Set the custom field name
			const char *pszName)
    {
	SetColumn(nRow, CUSTOM, pszName);
    }
  private:static const char *m_pszDefaultName[];
    // Initial database values
    static CustomFieldDB *m_pThis;	// Singleton pointer
    void Init();		// Initialize the database if empty
};


#endif /*  */

--- NEW FILE: NxDb0005.txt ---
not

--- NEW FILE: DatePicker.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Calendar widget.                                             //
//--------------------------------------------------------------//
#include "config.h"
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/fl_draw.H>
#include "DatePicker.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "Images.h"
#include "Options.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


#define DATE_MARGIN           6
#define DATE_BUTTON_WIDTH    24
#define DATE_LINE_HEIGHT     17
#define CALENDAR_WIDTH       (5*42)	// + 2 times border width
#define CALENDAR_HEIGHT      (11*DATE_LINE_HEIGHT+2*DATE_MARGIN)	// +4 times border height
#define MONTHLY_HEIGHT       (4*DATE_LINE_HEIGHT+DATE_MARGIN)


// Days per month for a leap year
const int
    DatePicker::m_nMDaysLeap[12] = {
	31,
	29,
	31,
	30,
	31,
	30,
	31,
	31,
	30,
	31,
	30,
31 };

// Days per month for a on-leap year
const int
    DatePicker::m_nMDaysNonLeap[12] = {
	31,
	28,
	31,
	30,
	31,
	30,
	31,
	31,
	30,
	31,
	30,
31 };


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
DatePicker::DatePicker(int nX, int nY, Type nType, time_t nTime)
    :
Fl_Group(nX,
	 nY,
	 CALENDAR_WIDTH + 2 * Fl::box_dx(FL_DOWN_BOX),
	 CALENDAR_HEIGHT + 4 * Fl::box_dy(FL_DOWN_BOX))
{
    Fl_Box *pBox;
    Fl_Button *pButton;
    int i;
    int j;
    int nBoxHeight = Fl::box_dy(FL_DOWN_BOX);
    int nBoxWidth = Fl::box_dx(FL_DOWN_BOX);
    int nButtonWidth;
    int nFontSize = (4 * labelsize()) / 5;
    int nWeekBegin;
    tm *pTm = localtime(&nTime);

    // Set no notification callback
    m_pfnCallback = NULL;

    // Set the type of this widget
    m_nType = nType;

    // Set the current date
    m_nDate = nTime;
    m_nDay = pTm->tm_mday;
    m_nDisplayMonth = m_nMonth = pTm->tm_mon;
    m_nDisplayYear = m_nYear = pTm->tm_year;

    // Create the first part for the year
    pButton = new Fl_Button(x(), y(), DATE_BUTTON_WIDTH, DATE_LINE_HEIGHT);
    m_pLeftPixmap = Images::GetLeftIcon();
    m_pLeftPixmap->label(pButton);
    pButton->callback(CallbackPriorYear);
    pButton =
	new Fl_Button(x() + CALENDAR_WIDTH + 2 * nBoxWidth -
		      DATE_BUTTON_WIDTH, y(), DATE_BUTTON_WIDTH,
		      DATE_LINE_HEIGHT);
    m_pRightPixmap = Images::GetRightIcon();
    m_pRightPixmap->label(pButton);
    pButton->callback(CallbackNextYear);
    m_pBoxYear = new Fl_Box(x() + DLG_BORDER + DATE_BUTTON_WIDTH,
			    y(),
			    CALENDAR_WIDTH + 2 * nBoxWidth - 2 * DLG_BORDER -
			    2 * DATE_BUTTON_WIDTH, DATE_LINE_HEIGHT);
    m_pBoxYear->align(FL_ALIGN_CENTER);
    m_pBoxYear->box(FL_DOWN_BOX);
    m_pBoxYear->color(FL_WHITE);
    m_pBoxYear->labelsize(nFontSize);
    m_pBoxYear->labelfont(FL_HELVETICA_BOLD);

    // Create two lines of buttons for months
    m_pGroupMonths = new Fl_Group(x(),
				  y() + DATE_LINE_HEIGHT + DATE_MARGIN,
				  w(), 2 * DATE_LINE_HEIGHT + 2 * nBoxHeight);
    m_pGroupMonths->box(FL_DOWN_BOX);
    m_pGroupMonths->color(FL_WHITE);
    nButtonWidth = (CALENDAR_WIDTH) / 6;
    for (i = 0; i < 2; ++i) {
	for (j = 0; j < 6; ++j) {
	    m_strMonthAbbr[i * 6 + j] =::GetMonthAbbr(i * 6 + j);
	    m_pMonthButton[i][j] =
		new Fl_Button(m_pGroupMonths->x() + j * nButtonWidth +
			      nBoxWidth,
			      m_pGroupMonths->y() + i * DATE_LINE_HEIGHT +
			      nBoxHeight, nButtonWidth, DATE_LINE_HEIGHT,
			      m_strMonthAbbr[i * 6 + j].c_str());
	    m_pMonthButton[i][j]->box(FL_BORDER_BOX);
	    m_pMonthButton[i][j]->callback(CallbackMonth);
	    m_pMonthButton[i][j]->user_data((void *) (i * 6 + j));
	    m_pMonthButton[i][j]->labelsize(nFontSize);
	    m_pMonthButton[i][j]->labelfont(FL_HELVETICA_BOLD);
	}
    }
    m_pGroupMonths->end();

    // Set up the day of month buttons only if this is not a monthly date picker
    if (m_nType != Monthly) {
	// Set up the day of month buttons
	m_pGroupDays = new Fl_Group(x(),
				    y() + 3 * DATE_LINE_HEIGHT +
				    2 * DATE_MARGIN + 2 * nBoxHeight, w(),
				    7 * DATE_LINE_HEIGHT + 2 * nBoxHeight);
	m_pGroupDays->box(FL_DOWN_BOX);
	m_pGroupDays->color(FL_WHITE);

	// Output the days of week
	nButtonWidth = CALENDAR_WIDTH / 7;
	nWeekBegin = Options::GetWeekBegins();
	for (i = 0; i < 7; ++i) {
	    // Get the first character of the day name
	    m_szWeekDay[i][0] = (::GetDayOfWeek((i + nWeekBegin) % 7))[0];
	    m_szWeekDay[i][1] = '\0';
	    pBox =
		new Fl_Box(m_pGroupDays->x() + nBoxWidth + i * nButtonWidth,
			   m_pGroupDays->y() + nBoxHeight, nButtonWidth,
			   DATE_LINE_HEIGHT, m_szWeekDay[i]);
	    pBox->box(FL_FLAT_BOX);
	    pBox->color(FL_GRAY);
	    pBox->labelsize(nFontSize);
	    pBox->labelfont(FL_HELVETICA_BOLD);
	}

	// Now create the day of month buttons
	for (i = 0; i < 6; ++i) {
	    for (j = 0; j < 7; ++j) {
		// Create the button
		m_pDateButton[i][j] =
		    new Fl_Button(m_pGroupDays->x() + j * nButtonWidth +
				  nBoxWidth,
				  m_pGroupDays->y() + (i +
						       1) * DATE_LINE_HEIGHT +
				  nBoxHeight, nButtonWidth, DATE_LINE_HEIGHT,
				  "");
		m_pDateButton[i][j]->box(FL_FLAT_BOX);
		m_pDateButton[i][j]->labelsize(nFontSize);
		m_pDateButton[i][j]->labelfont(FL_HELVETICA_BOLD);
		m_pDateButton[i][j]->color(FL_WHITE);
		m_pDateButton[i][j]->callback(DateButtonCallback);
	    }
	}
	m_pGroupDays->end();
    }
    // Finish this widget
    end();

    // Set up for the first draw event
    PreDraw(true);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
DatePicker::~DatePicker()
{
    delete m_pLeftPixmap;
    delete m_pRightPixmap;
}


//--------------------------------------------------------------//
// Go to a particular month                                     //
//--------------------------------------------------------------//
void
DatePicker::CallbackMonth(Fl_Widget * pWidget, void *pUserData)
{
    reinterpret_cast <
	DatePicker *
	>(pWidget->parent()->parent())->SetMonth(reinterpret_cast <
						 int >(pUserData));
}


//--------------------------------------------------------------//
// Go to the next year                                         //
//--------------------------------------------------------------//
void
DatePicker::CallbackNextYear(Fl_Widget * pWidget, void *pUserData)
{
    reinterpret_cast < DatePicker * >(pWidget->parent())->IncrementYear();
}


//--------------------------------------------------------------//
// Go to the prior year                                         //
//--------------------------------------------------------------//
void
DatePicker::CallbackPriorYear(Fl_Widget * pWidget, void *pUserData)
{
    reinterpret_cast < DatePicker * >(pWidget->parent())->DecrementYear();
}


//--------------------------------------------------------------//
// Date button callback.                                        //
//--------------------------------------------------------------//
void
DatePicker::DateButtonCallback(Fl_Widget * pWidget, void *pUserData)
{
    DatePicker *pThis =
	reinterpret_cast < DatePicker * >(pWidget->parent()->parent());
    int nUserData = (int) pUserData;

    pThis->m_nYear = nUserData / 10000;
    pThis->m_nMonth = ((nUserData / 100) % 100);
    pThis->m_nDay = (nUserData % 100);
    pThis->PreDraw(false);
}


//--------------------------------------------------------------//
// Decrement the year.                                          //
//--------------------------------------------------------------//
void
DatePicker::DecrementYear()
{
    // Don't decrement below 1970
    if (m_nYear > 70) {
	--m_nYear;
	m_nDisplayYear = 68;	// To cause a display month reset
	FixDate(false);
    }
}


//--------------------------------------------------------------//
// Fix a date after it has been changed.  The bFallback         //
// variable controls how a day of month is corrected when the   //
// day of month is too high.  If true then the last day of the  //
// prior month is chosen instead.                               //
//--------------------------------------------------------------//
void
DatePicker::FixDate(bool bFallback)
{
    const int *pnMDays;

    // Test if the date is too low
    if (m_nYear < 70 || (m_nYear == 70 && m_nMonth < 0)
	|| (m_nYear == 70 && m_nMonth == 0 && m_nDay < 1)) {
	// Date too low
	m_nYear = 70;
	m_nMonth = 0;
	m_nDay = 1;
    } else if (m_nYear > 136 || (m_nYear == 136 && m_nMonth > 11)
	       || (m_nYear == 136 && m_nMonth == 11 && m_nDay > 31)) {
	// Date too high
	m_nYear = 136;
	m_nMonth = 11;
	m_nDay = 31;
    } else {
	// Fix the date if the month or day is out-of-range
	while (m_nMonth < 0) {
	    m_nMonth += 12;
	    --m_nYear;
	}

	while (m_nMonth > 11) {
	    m_nMonth -= 12;
	    ++m_nYear;
	}

	// Correct for days out-of-range
	pnMDays = (m_nYear & 0x03) != 0 ? m_nMDaysNonLeap : m_nMDaysLeap;
	while (m_nDay < 1) {
	    --m_nMonth;
	    if (m_nMonth < 0) {
		m_nMonth += 12;
		--m_nYear;
		pnMDays =
		    (m_nYear & 0x03) != 0 ? m_nMDaysNonLeap : m_nMDaysLeap;
	    }
	    m_nDay += pnMDays[m_nMonth];
	}

	if (bFallback == true) {
	    // Fall back to the prior month
	    if (m_nDay > pnMDays[m_nMonth]) {
		m_nDay = pnMDays[m_nMonth];
	    }
	} else {
	    // Don't fall back
	    while (m_nDay > pnMDays[m_nMonth]) {
		m_nDay -= pnMDays[m_nMonth];
		++m_nMonth;
		if (m_nMonth > 11) {
		    m_nMonth -= 12;
		    ++m_nYear;
		    pnMDays =
			(m_nYear & 0x03) !=
			0 ? m_nMDaysNonLeap : m_nMDaysLeap;
		}
	    }
	}
    }

    PreDraw(false);
}


//--------------------------------------------------------------//
// Get the height of the calendar widget                        //
//--------------------------------------------------------------//
int
DatePicker::GetHeight(Type nType)
{
    return (nType == Monthly ? MONTHLY_HEIGHT + 2 * Fl::box_dy(FL_DOWN_BOX)
	    : CALENDAR_HEIGHT + 4 * Fl::box_dy(FL_DOWN_BOX));
}


//--------------------------------------------------------------//
// Get the width of the calendar widget                         //
//--------------------------------------------------------------//
int
DatePicker::GetWidth()
{
    return (CALENDAR_WIDTH + 2 * Fl::box_dx(FL_DOWN_BOX));
}


//--------------------------------------------------------------//
// Increment the year.                                          //
//--------------------------------------------------------------//
void
DatePicker::IncrementYear()
{
    // Don't increment above 2036
    if (m_nYear < 136) {
	++m_nYear;
	m_nDisplayYear = 68;	// To cause a display month reset
	FixDate(false);
    }
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
DatePicker::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case BEGIN_WEEK_CHANGED:	// Beginning day of week has changed
	{
	    int i;
	    int nWeekBegin;

	    // Set up the day of month buttons only if this is not a monthly date picker
	    if (m_nType != Monthly) {
		// Output the days of week
		nWeekBegin = Options::GetWeekBegins();
		for (i = 0; i < 7; ++i) {
		    // Get the first character of the day name
		    m_szWeekDay[i][0] =
			(::GetDayOfWeek((i + nWeekBegin) % 7))[0];
		    m_szWeekDay[i][1] = '\0';
		}

		// Go redraw the calendar
		PreDraw(true);
	    }
	}
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Set up for the next draw event.                              //
//--------------------------------------------------------------//
void
DatePicker::PreDraw(bool bProgramSet)
{
    bool bReset;
    Fl_Color nColor;
    Fl_Color nGray = GetFLTKColor(0xa0, 0xa0, 0xa0);
    Fl_Color nLabelColor;
    int i;
    int j;
    int nCumDisplayMonth;
    int nCumMonth;
    int nDay;
    int nDays;
    int nPriorDays;
    int nUserData;
    int nWDay;
    int nWeekBegin = Options::GetWeekBegins();
    const int *pnMDays;
    time_t timeCurrent = NormalizeDate(time(NULL));
    time_t timeDisplay;
    time_t timeValue;
    tm *pTm;

    // Fix the date for weekly or monthly options
    if (m_nType == Weekly) {
	time_t nDate;
	struct tm *pTm;

	nDate =::MakeDate(m_nYear, m_nMonth, m_nDay);
	nDays =::GetDow(nDate) - nWeekBegin;
	if (nDays < 0) {
	    nDays += 7;
	}
	nDate =::SubtractDays(nDate, nDays);
	pTm = localtime(&nDate);
	m_nDay = pTm->tm_mday;
	m_nMonth = pTm->tm_mon;
	m_nYear = pTm->tm_year;
    } else if (m_nType == Monthly) {
	m_nDay = 1;
    }
    // Get the selected date
    m_nDate = MakeDate(m_nYear, m_nMonth, m_nDay);

    // Get the day of week of the first day of the display month
    if (m_nDisplayYear >= 70) {
	timeDisplay = MakeDate(m_nDisplayYear, m_nMonth, 1);
    } else {
	// Fake a very low date but allow for a timeozne offset
	timeDisplay = 24 * 60 * 60 - 1;
    }
    pTm = localtime(&timeDisplay);

    // See if the display month still works for the selected date
    nCumDisplayMonth = 12 * m_nDisplayYear + m_nDisplayMonth;
    nCumMonth = 12 * m_nYear + m_nMonth;
    bReset = false;
    if (nCumDisplayMonth == nCumMonth + 1) {
	if ((m_nYear % 4) == 0) {
	    nDay = m_nMDaysLeap[m_nMonth] - pTm->tm_wday;
	} else {
	    nDay = m_nMDaysNonLeap[m_nMonth] - pTm->tm_wday;
	}
	if (nDay > m_nDay) {
	    bReset = true;
	}
    } else if (nCumDisplayMonth == nCumMonth - 1) {
	if ((m_nDisplayYear % 4) == 0) {
	    nDay = m_nMDaysLeap[m_nDisplayMonth] + pTm->tm_wday;
	} else {
	    nDay = m_nMDaysNonLeap[m_nDisplayMonth] + pTm->tm_wday;
	}
	if (m_nDay > (6 * 7) - nDay + 1) {
	    bReset = true;
	}
    } else if (nCumDisplayMonth != nCumMonth) {
	bReset = true;
    }
    if (bReset == true) {
	m_nDisplayMonth = m_nMonth;
	m_nDisplayYear = m_nYear;
    }
    // Set up the year banner
    sprintf(m_szYear, "%d", m_nDisplayYear + 1900);
    m_pBoxYear->label(m_szYear);

    // Set the colors of the month buttons
    for (i = 0; i < 12; ++i) {
	if (i == m_nDisplayMonth) {
	    nColor = FL_SELECTION_COLOR;
	    nLabelColor = FL_WHITE;
	} else {
	    nColor = FL_WHITE;
	    nLabelColor = FL_BLACK;
	}
	m_pMonthButton[i / 6][i % 6]->color(nColor);
	m_pMonthButton[i / 6][i % 6]->labelcolor(nLabelColor);
    }

    // Set up the date buttons only if this is not a monthly date picker
    if (m_nType != Monthly) {
	// Get the day of week of the current month
	timeValue = MakeDate(m_nDisplayYear, m_nDisplayMonth, 1);
	pTm = localtime(&timeValue);

	// Correct for the day of week of the start of this month
	nWDay = pTm->tm_wday - nWeekBegin;
	if (nWDay < 0) {
	    nWDay += 7;
	}
	timeValue = SubtractDays(timeValue, nWDay);

	// Get the number of days in the prior month
	pnMDays = (m_nYear & 0x03) != 0 ? m_nMDaysNonLeap : m_nMDaysLeap;
	if (m_nMonth == 0) {
	    // For January, this must have been December
	    nPriorDays = 31;
	} else {
	    nPriorDays = pnMDays[m_nMonth - 1];
	}

	// Set up each button
	for (i = 0; i < 6; ++i) {
	    for (j = 0; j < 7; ++j) {
		nDay = i * 7 + j - nWDay + 1;
		nColor = FL_WHITE;
		if (nDay <= 0) {
		    nDay += nPriorDays;
		    nLabelColor = nGray;
		    if (nDay == m_nDay
			&& (m_nMonth + 1 == m_nDisplayMonth
			    || (m_nMonth == 11 && m_nDisplayMonth == 0))) {
			nColor = FL_SELECTION_COLOR;
			nLabelColor = FL_WHITE;
		    }
		    nUserData =
			10000 * (m_nDisplayYear -
				 (m_nDisplayMonth == 0 ? 1 : 0))
			+ 100 * (m_nDisplayMonth ==
				 0 ? 12 : (m_nDisplayMonth - 1))
			+ nDay;
		} else if (nDay > pnMDays[m_nDisplayMonth]) {
		    nDay -= pnMDays[m_nDisplayMonth];
		    nLabelColor = nGray;
		    if (nDay == m_nDay
			&& (m_nMonth - 1 == m_nDisplayMonth
			    || (m_nMonth == 0 && m_nDisplayMonth == 11))) {
			nColor = FL_SELECTION_COLOR;
			nLabelColor = FL_WHITE;
		    }
		    nUserData =
			10000 * (m_nDisplayYear +
				 (m_nDisplayMonth == 11 ? 1 : 0))
			+ 100 * (m_nDisplayMonth ==
				 11 ? 1 : (m_nDisplayMonth + 1))
			+ nDay;
		} else {
		    nUserData =
			10000 * m_nDisplayYear + 100 * m_nDisplayMonth + nDay;
		    if (timeValue == timeCurrent) {
			nLabelColor = FL_RED;
		    } else {
			nLabelColor = FL_BLACK;
		    }
		    if (nDay == m_nDay && m_nMonth == m_nDisplayMonth) {
			nColor = FL_SELECTION_COLOR;
			nLabelColor = FL_WHITE;
		    }
		}

		// Set the button selection if this is a weekly date picker
		if (m_nType == Weekly) {
		    int nDiff;

		    nDiff =::DaysBetween(m_nYear, m_nMonth, m_nDay,
					 timeValue);
		    if (nDiff >= -6 && nDiff <= 0) {
			nColor = FL_SELECTION_COLOR;
			nLabelColor = FL_WHITE;
		    }
		}

		sprintf(m_szDay[i][j], "%d", nDay);
		m_pDateButton[i][j]->label(m_szDay[i][j]);
		m_pDateButton[i][j]->color(nColor);
		m_pDateButton[i][j]->labelcolor(nLabelColor);
		m_pDateButton[i][j]->user_data((void *) nUserData);
		timeValue =::AddDays(timeValue, 1);
	    }
	}
    }
    // If not programmatically set, notify (someone) about the change in date if needed
    if (bProgramSet == false && m_pfnCallback != NULL) {
	(*m_pfnCallback) (this, m_nDate);
    }
    // Redraw the entire widget
    redraw();
}


//--------------------------------------------------------------//
// Set to a particular month.                                   //
//--------------------------------------------------------------//
void
DatePicker::SetMonth(int nMonth)
{
    m_nMonth = nMonth;
    m_nDisplayYear = 68;	// To cause a display month reset
    FixDate(true);
}


//--------------------------------------------------------------//
// Set to a particular date.                                    //
//--------------------------------------------------------------//
void
DatePicker::SetDate(time_t nDate)
{
    struct tm *pTm;

    // Fix the date
    m_nDate = NormalizeDate(nDate);
    pTm = localtime(&m_nDate);
    if (m_nYear != pTm->tm_year
	|| m_nMonth != pTm->tm_mon || m_nDay != pTm->tm_mday) {
	m_nYear = m_nDisplayYear = pTm->tm_year;
	m_nMonth = m_nDisplayMonth = pTm->tm_mon;
	m_nDay = pTm->tm_mday;

	// Go redraw the control
	PreDraw(true);
    }
}

--- NEW FILE: InputBox.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// A class that will present a dialog just like "fl_input"      //
// except that the size of the input field can be limited.      //
//--------------------------------------------------------------//
#include "config.h"
#include <cassert>
#include <FL/fl_ask.H>
#include "FLTKUtil.h"
#include "HelpID.h"
#include "InputBox.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#define DLG_HEIGHT 103
#define DLG_WIDTH  410


//--------------------------------------------------------------//
// Constructor                                                  //
// Just like "fl_input" but will limit the text size of the     //
// input field.                                                 //
//--------------------------------------------------------------//
InputBox::InputBox(const char *pszTitle,
		   Fl_Widget * pParent,
		   const char *pszDefault,
		   int nMaxSize,
		   enum HelpID nHelpID,
		   VALIDATE_FUNC pfnValidate,
		   Fl_Widget * pValidateWidget,
		   void *pValidateData, const char *pszFmt, ...)
    :
Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, pszTitle)
{
    va_list ap;

    m_nMaxSize = nMaxSize;
    m_nHelpID = nHelpID;
    m_pfnValidate = pfnValidate;
    m_pValidateWidget = pValidateWidget;
    m_pValidateData = pValidateData;
    va_start(ap, pszFmt);
    FormatPrompt(pszFmt, ap);
    va_end(ap);
    RunInput(pszDefault);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
InputBox::~InputBox()
{
}


//--------------------------------------------------------------//
// Format the prompt for the input box, almost the same as      //
// vsprintf.                                                    //
//--------------------------------------------------------------//
void
InputBox::FormatPrompt(const char *pszFmt, va_list ap)
{
    char *pszPrompt = new char[1024];

#ifdef DEBUG
    int nResult = vsprintf(pszPrompt, pszFmt, ap);
    assert(nResult < 1023);	// Too much output from vsprintf
#else
    vsprintf(pszPrompt, pszFmt, ap);
#endif
    m_strPrompt = pszPrompt;
    delete[]pszPrompt;
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
InputBox::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    InputBox *pThis = reinterpret_cast < InputBox * >(pWidget->parent());

    PixilDT::GetApp()->ShowHelp(pThis->m_nHelpID);
}


//--------------------------------------------------------------//
// Run the dialog                                               //
//--------------------------------------------------------------//
void
InputBox::RunInput(const char *pszDefault)
{
    char *pszString = new char[m_nMaxSize + 1];
    int nHeight;
    int nWidth;

    // Set the size of the input field based on the maximum number of characters
    fl_font(labelfont(), labelsize());
    memset(pszString, 'M', m_nMaxSize);
    pszString[m_nMaxSize] = '\0';
    fl_measure(pszString, nWidth, nHeight);
    delete[]pszString;
    if (nWidth > 340) {
	nWidth = 340;
    }

    m_pMessage = new Fl_Box(60, 10, 340, 20);
    m_pMessage->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
    m_pMessage->label(m_strPrompt.c_str());
    m_pInput = new Fl_Input(60, 37, nWidth, 23);
    m_pInput->hide();
    m_pInput->type(FL_NORMAL_INPUT);
    m_pInput->show();
    m_pInput->value(pszDefault);
    m_pInput->maximum_size(m_nMaxSize);
    m_pIcon = new Fl_Box(10, 10, 50, 50);
    m_pIcon->box(FL_THIN_UP_BOX);
    m_pIcon->label("?");
    m_pIcon->labelfont(FL_TIMES_BOLD);
    m_pIcon->labelsize(34);
    m_pIcon->color(FL_WHITE);
    m_pIcon->labelcolor(FL_BLUE);
    m_pButton[0] = new Fl_Button(310, 70, 90, 23);
    m_pButton[0]->shortcut("^[");
    m_pButton[0]->label(fl_cancel);
    m_pButton[1] = new Fl_Return_Button(210, 70, 90, 23);
    m_pButton[1]->label(fl_ok);
    m_pButton[2] = new Fl_Button(110, 70, 90, 23);
    m_pButton[2]->label(_("&Help"));
    m_pButton[2]->callback(OnHelpButton);
    resizable(new Fl_Box(60, 10, 110 - 60, 27));
    end();

#ifdef WIN32
    MessageBeep(MB_ICONQUESTION);
#endif // WIN32

    // Stay modal until a good string is entered
    while (DoModal(this, m_pButton[1], m_pButton[0]) == 1) {
	// Validate the string if a validation function exists
	if (m_pfnValidate == NULL
	    || m_pfnValidate(m_pInput->value(), m_pValidateWidget,
			     m_pValidateData) == true) {
	    // Save the input string and quit this loop
	    m_strReply = m_pInput->value();
	    break;
	}
    }
}

--- NEW FILE: Scheduler.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Center of the window for the Scheduler display               //
//--------------------------------------------------------------//
#include "config.h"
#include <cassert>
#include <FL/fl_ask.H>
#include "Dialog.h"
#include "Options.h"
#include "PixilDT.h"
#include "Scheduler.h"
#include "SchedulerChangeTypeDlg.h"
#include "SchedulerDB.h"
#include "SchedulerDlg.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Default constructor                                          //
//--------------------------------------------------------------//
Scheduler::Scheduler(Fl_Widget * pParent)
:  Fl_Group(pParent->x(), pParent->y(), pParent->w(), pParent->h())
{
    Fl_Widget *pWidget;

    m_pTab = new Fl_Tabs(x() + DLG_BORDER,
			 y() + DLG_BORDER,
			 w() - 2 * DLG_BORDER, h() - 2 * DLG_BORDER);

    // Create the tab pages
    m_pDailyPage = new SchedulerDaily(m_pTab->x(),
				      m_pTab->y(),
				      m_pTab->w(),
				      m_pTab->h() - DLG_TAB_HEIGHT);
    m_pWeeklyPage = new SchedulerWeekly(m_pTab->x(),
					m_pTab->y(),
					m_pTab->w(),
					m_pTab->h() - DLG_TAB_HEIGHT);
    m_pMonthlyPage = new SchedulerMonthly(m_pTab->x(),
					  m_pTab->y(),
					  m_pTab->w(),
					  m_pTab->h() - DLG_TAB_HEIGHT);
    m_pYearlyPage = new SchedulerYearly(m_pTab->x(),
					m_pTab->y(),
					m_pTab->w(),
					m_pTab->h() - DLG_TAB_HEIGHT);

    // Finish this group
    end();

    // Display the most recently used page
    switch (Options::GetSchedulerPage()) {
    case 1:
	pWidget = m_pWeeklyPage;
	break;

    case 2:
	pWidget = m_pMonthlyPage;
	break;

    case 3:
	pWidget = m_pYearlyPage;
	break;

    default:			// Includes case 0 for daily
	pWidget = m_pDailyPage;
    }
    m_pTab->value(pWidget);

    // Set that this is resizable
    m_pTab->resizable(m_pDailyPage);
    resizable(m_pTab);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
Scheduler::~Scheduler()
{
}


//--------------------------------------------------------------//
// Delete an appointment                                        //
//--------------------------------------------------------------//
void
Scheduler::Delete(int nRow, time_t nDate)
{
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();
    int nContinue;

#ifdef DEBUG
    assert(nDate ==::NormalizeDate(nDate));	// Date must be normailized
#endif

    if (pSchedulerDB->GetRepeatingFlag(nRow) == false) {
	// Not a repeating or exception event
	if (Options::GetConfirmDelete() == true) {
	    nContinue =
		fl_ask(_("Delete Appointment for %s %s ?"),::
		       FormatDate(pSchedulerDB->GetStartTime(nRow)).
		       c_str(),::FormatTime(pSchedulerDB->GetStartTime(nRow)).
		       c_str());
	    nContinue =
		(nContinue ==
		 1 ? SCHEDULER_CHANGE_TYPE_ALL : SCHEDULER_CHANGE_TYPE_NONE);
	} else {
	    nContinue = SCHEDULER_CHANGE_TYPE_ALL;
	}
    } else {
	// A repeating or exception event
	SchedulerChangeTypeDlg *pDlg = new SchedulerChangeTypeDlg(this, true);

	pDlg->DoModal();
	nContinue = pDlg->GetChangeType();
	delete pDlg;
    }

    if (nContinue == SCHEDULER_CHANGE_TYPE_ALL) {
	// Delete this item and all exceptions related to it
	pSchedulerDB->Delete(nRow);
    } else if (nContinue == SCHEDULER_CHANGE_TYPE_CURRENT_FUTURE) {
	// End this repeating event prior to the date in question
	pSchedulerDB->EndRepetitions(nRow, nDate);
    } else if (nContinue == SCHEDULER_CHANGE_TYPE_CURRENT_ONLY) {
	// Insert a deleted exception for this date
	pSchedulerDB->AddDeletedException(nRow, nDate);
    }
    // Save the changes if any occurred
    if (nContinue > 0) {
	pSchedulerDB->Save();
	PixilDT::GetApp()->GetMainWindow()->Notify(SCHEDULER_CHANGED, 0);
    }
}


//--------------------------------------------------------------//
// Edit an appointment                                          //
//--------------------------------------------------------------//
void
Scheduler::Edit(int nRow, time_t nDate)
{
    SchedulerDlg *pSchedulerDlg;

#ifdef DEBUG
    assert(nDate ==::NormalizeDate(nDate));	// The date must be normalized
#endif

    pSchedulerDlg = new SchedulerDlg(nRow,
				     nDate,
				     PixilDT::GetApp()->GetMainWindow());
    if (pSchedulerDlg->DoModal() == 1) {
	// OK button was pressed, refresh displays
	PixilDT::GetApp()->GetMainWindow()->Notify(SCHEDULER_CHANGED, 0);
    }
    delete pSchedulerDlg;
}


//--------------------------------------------------------------//
// Add a new appointment                                        //
//--------------------------------------------------------------//
void
Scheduler::EditNew(time_t nDate)
{
    SchedulerDlg *pSchedulerDlg = new SchedulerDlg(-1,
						   nDate,
						   PixilDT::GetApp()->
						   GetMainWindow());

    if (pSchedulerDlg->DoModal() == 1) {
	// OK button was pressed, refresh displays
	PixilDT::GetApp()->GetMainWindow()->Notify(SCHEDULER_CHANGED, 0);
    }
    delete pSchedulerDlg;
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
Scheduler::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case ADDRESS_BOOK_CHANGED:	// Fix the address book display
    case TODO_LIST_CHANGED:	// Fix the to do list display
	m_pDailyPage->Message(nMessage, nInfo);
	break;

    case BEGIN_WEEK_CHANGED:	// Beginning day of week has changed
    case SCHEDULER_CHANGED:	// Scheduler data changed, go refresh the display
	m_pDailyPage->Message(nMessage, nInfo);
	m_pWeeklyPage->Message(nMessage, nInfo);
	m_pMonthlyPage->Message(nMessage, nInfo);
	m_pYearlyPage->Message(nMessage, nInfo);
	break;

    case SELECTION_CHANGING:	// No processing needed here
	nReturn = 1;		// Set no errors occurred
	break;

    case SCHEDULER_GOTO:	// Find dialog has requested the display of an appointment
	{
	    int nRow;
	    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();
	    time_t nStartTime;

	    m_pTab->value(m_pDailyPage);
	    nRow = pSchedulerDB->FindPhysicalRecord(nInfo);
	    nStartTime = pSchedulerDB->GetStartTime(nRow);
	    m_pDailyPage->DisplayDay(nStartTime);
	    Edit(nRow,::NormalizeDate(nStartTime));
	}
	break;

    case SCHEDULER_PRINT:
	if (m_pTab->value() == m_pDailyPage) {
	    m_pDailyPage->Print();
	} else if (m_pTab->value() == m_pWeeklyPage) {
	    m_pWeeklyPage->Print();
	} else if (m_pTab->value() == m_pMonthlyPage) {
	    m_pMonthlyPage->Print();
	} else if (m_pTab->value() == m_pYearlyPage) {
	    m_pYearlyPage->Print();
	}
	break;

    case ADDRESS_BOOK_REQUESTED:	// Selection changing, no processing needed
    case NOTES_REQUESTED:	// Selection changing, no processing needed
    case SCHEDULER_REQUESTED:	// Selection changing, no processing needed
    case TODO_LIST_REQUESTED:	// Selection changing, no processing needed
	break;

    case APPLICATION_CLOSING:	// Save the most recently selected page to the INI file
	{
	    Fl_Widget *pWidget = m_pTab->value();
	    int nValue;

	    // Set the most recently used page
	    if (pWidget == m_pWeeklyPage) {
		nValue = 1;
	    } else if (pWidget == m_pMonthlyPage) {
		nValue = 2;
	    } else if (pWidget == m_pYearlyPage) {
		nValue = 3;
	    } else {
		// Must be the daily page
		nValue = 0;
	    }
	    Options::SetSchedulerPage(nValue);
	}
	break;

    case EDIT_COPY_AVAILABLE:	// No cut/copy/paste or undo allowed
    case EDIT_CUT_AVAILABLE:
    case EDIT_PASTE_AVAILABLE:
    case EDIT_UNDO_AVAILABLE:
	nReturn = 0;
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Select and display a given day.                              //
//--------------------------------------------------------------//
void
Scheduler::SelectDay(time_t nDate)
{
    m_pDailyPage->DisplayDay(nDate);
    m_pTab->value(m_pDailyPage);
}

--- NEW FILE: ToDoListDB.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// ToDo List database class.                                    //
//--------------------------------------------------------------//
#ifndef TODOLISTDB_H_

#define TODOLISTDB_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <vector>
#include "NxDbAccess.h"
using namespace std;

// Field References
#define TODO_ID         0
#define TODO_CAT        1
#define TODO_COMPLETE   2
#define TODO_PRIORITY   3
#define TODO_TITLE      4
#define TODO_DESC       5
#define TODO_TIME       6
#define TODO_NUM_FIELDS 7

#define TODO_TITLE_LEN 100
#define TODO_DESC_LEN  100
class ToDoListDB:public NxDbAccess
{
  public:ToDoListDB();		// Constructor
    ~ToDoListDB();		// Destructor
    inline int GetCategory(int nRow) const	// Get the Category
    {
	return (GetIntValue(nRow, TODO_CAT));
    }
    string GetCategoryName(int nRow) const;	// Get the name of the category
    inline int GetComplete(int nRow) const	// Get the complete flag
    {
	return (GetIntValue(nRow, TODO_COMPLETE));
    }
    inline string GetDescription(int nRow) const	// Get the description
    {
	return (GetStringValue(nRow, TODO_DESC));
    }
    inline int GetID(int nRow) const	// Get the ID
    {
	return (GetIntValue(nRow, TODO_ID));
    }
    inline int GetPriority(int nRow) const	// Get the priority
    {
	return (GetIntValue(nRow, TODO_PRIORITY));
    }
    inline int GetTime(int nRow) const	// Get the time
    {
	return (GetIntValue(nRow, TODO_TIME));
    }
    string GetTimeString(int nRow) const;	// Get the time as a string
    inline string GetTitle(int nRow) const	// Get the title
    {
	return (GetStringValue(nRow, TODO_TITLE));
    }
    static ToDoListDB *GetToDoListDB();	// Get the singleton pointer
    int Import(const vector < string > &strData);	// Import a delimited string
    int Insert(int nCategory);	// Insert a row and set its key value
    inline void SetCategory(int nRow, int nCategory)	// Set the category
    {
	SetColumn(nRow, TODO_CAT, nCategory);
    }
    inline void SetComplete(int nRow, int nComplete)	// Set the complete flag
    {
	SetColumn(nRow, TODO_COMPLETE, nComplete);
    }
    inline void SetDescription(int nRow, const char *pszDesc)	// Set the description
    {
	SetColumn(nRow, TODO_DESC, pszDesc);
    }
    inline void SetID(int nRow, int nID)	// Set the ID
    {
	SetColumn(nRow, TODO_ID, nID);
    }
    inline void SetPriority(int nRow, int nPriority)	// Set the priority
    {
	SetColumn(nRow, TODO_PRIORITY, nPriority);
    }
    inline void SetTime(int nRow, int nTime)	// Set the time
    {
	SetColumn(nRow, TODO_TIME, nTime);
    }
    inline void SetTitle(int nRow, const char *pszTitle)	// Set the title
    {
	SetColumn(nRow, TODO_TITLE, pszTitle);
    }
  private:static ToDoListDB *m_pThis;
    // One and only object
};


#endif /*  */

--- NEW FILE: ToDoListCategoryDB.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// ToDo List Category database definition fields.               //
//--------------------------------------------------------------//
#include "ToDoListCategoryDB.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Pointer to the only one of these objects.                    //
//--------------------------------------------------------------//
ToDoListCategoryDB *
    ToDoListCategoryDB::m_pThis =
    NULL;


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
ToDoListCategoryDB::ToDoListCategoryDB()
:  CategoryDB("td_category", 10)
{
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
ToDoListCategoryDB::~ToDoListCategoryDB()
{
    m_pThis = NULL;
}


//--------------------------------------------------------------//
// Get a pointer to an open data base.                          //
//--------------------------------------------------------------//
ToDoListCategoryDB *
ToDoListCategoryDB::GetToDoListCategoryDB()
{
    if (m_pThis == NULL) {
	m_pThis = new ToDoListCategoryDB;
    }
    return (m_pThis);
}

--- NEW FILE: Makefile ---
# apps/address/Makefile

DEST_DIR?=$(ROOT_DIR)

# Indicate that we want to build this natively
BUILD_NATIVE=y

ifeq ($(CONFIG_PIXILDT_INTERNATIONAL),y)
GETTEXT=/usr/share/gettext
CFLAGS=-I$(GETTEXT)
endif

TARGET_CXX=PixilDT
INSTALL_BINDIR=$(PIXILDT_DIR)/bin

SRC=${shell ls *.cpp} 
OBJS=${SRC:.cpp=.o}

ifeq ($(CONFIG_SYNC),y)
INCLUDES=-I../sync/
endif

CFLAGS += -DDB_DIR="\"$(DEST_DIR/workstation/data)\""

LIBS= -L$(BASE_DIR)/pixilDT/flek -lflek

ifeq ($(CONFIG_PIXILDT_FLTK),y)
LIBS += -L$(FLTKDIR)/lib -lfltk
else
LIBS += -L$(BASE_DIR)/pixilDT/fltk -lfltk
endif

LIBS += ../NxDb/libNxDb.a 

ifeq ($(CONFIG_SYNC),y)
LIBS += ../sync/libpixil-sync-native.a
endif

LIBS += -lX11

include $(BASE_DIR)/Rules.make


--- NEW FILE: ToDoListShowDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// To Do List Show Dialog.                                      //
//--------------------------------------------------------------//
#ifndef TODOLISTSHOWDLG_H_

#define TODOLISTSHOWDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Window.H>
class ToDoListShowDlg:public Fl_Window
{
  public:ToDoListShowDlg(Fl_Widget * pParent);
    // Constructor
    ~ToDoListShowDlg();		// Destructor
    int DoModal();		// Run the modal dialog
  private:  Fl_Button * m_pCancelButton;
    // The Cancel button
    Fl_Button *m_pHelpButton;	// The Help button
    Fl_Button *m_pOKButton;	// The OK button
    Fl_Check_Button *m_pCategoryButton;	// Show categories check button
    Fl_Check_Button *m_pCompletedButton;	// Show Completed check button
    Fl_Check_Button *m_pDueButton;	// Show only due items check button
    Fl_Check_Button *m_pDueDateButton;	// Show due dates check button
    Fl_Check_Button *m_pPriorityButton;	// Show priorities check button
    Fl_Choice *m_pSortChoice;	// The sort choice widget
    Fl_Menu_Item *m_pSortMenu;	// The menu for the Sort choice widget
    void CreateOrderWidget(int nX,	// Create the sort order choice widget
			   int nY, int nWidth, int nHeight);
    static void OnHelpButton(Fl_Widget * pWidget,	// Process click on the Help button
			     void *pUserData);
};


#endif /*  */

--- NEW FILE: ToDoListDetails.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the ToDo List Details.                             //
//--------------------------------------------------------------//
#include "config.h"
#include <ctime>
#include <FL/fl_ask.H>
#include "DatePickerDlg.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "Images.h"
#include "NoteEditorDlg.h"
#include "PixilDT.h"
#include "TimeFunc.h"
#include "ToDoListDB.h"
#include "ToDoListDetails.h"
#include "ToDoListCategoryDB.h"

#include "VCMemoryLeak.h"


#define DATE_INPUT_WIDTH   84
#define PRIORITY_WIDTH     16
#define PROMPT_BORDER       3
#define PROMPT_WIDTH       80


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
ToDoListDetails::ToDoListDetails(int nX, int nY, int nWidth, int nHeight)
    :
Fl_Group(nX, nY, nWidth, nHeight)
{
    Fl_Box *pBox;
    Fl_Group *pGroup;
    int i;
    int nButtonWidth;
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();

    // Create widgets for this object
    pBox = new Fl_Box(x(), y(), PROMPT_WIDTH, DLG_INPUT_HEIGHT, _("Title:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_BOTTOM | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    m_pTitle =
	new Fl_Multiline_Input(x() + PROMPT_WIDTH + PROMPT_BORDER, y(),
			       w() - PROMPT_BORDER - PROMPT_WIDTH,
			       2 * DLG_INPUT_HEIGHT);
    m_pTitle->maximum_size(pToDoListDB->GetColumnSize(TODO_TITLE));
    pBox = new Fl_Box(x(),
		      y() + 2 * DLG_INPUT_HEIGHT + DLG_BORDER,
		      PROMPT_WIDTH,
		      DLG_BUTTON_HEIGHT + 2 * DLG_BORDER, _("Priority:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    pGroup =
	new Fl_Group(x() + PROMPT_WIDTH + PROMPT_BORDER,
		     y() + 2 * DLG_INPUT_HEIGHT + DLG_BORDER,
		     w() - PROMPT_WIDTH - PROMPT_BORDER,
		     DLG_BUTTON_HEIGHT + 2 * DLG_BORDER);
    pGroup->box(FL_EMBOSSED_FRAME);
    nButtonWidth = (pGroup->w() - 4 * DLG_BORDER) / (5 - 1);
    for (i = 0; i < 5; ++i) {
	m_szLabel[i][0] = i + '1';
	m_szLabel[i][1] = '\0';
	m_pPriority[i] =
	    new Fl_Button(x() + PROMPT_WIDTH + PROMPT_BORDER + DLG_BORDER +
			  i * nButtonWidth,
			  y() + 2 * DLG_INPUT_HEIGHT + 2 * DLG_BORDER,
			  PRIORITY_WIDTH, DLG_BUTTON_HEIGHT, m_szLabel[i]);
	m_pPriority[i]->type(FL_RADIO_BUTTON);
    }
    pGroup->end();
    pBox = new Fl_Box(x(),
		      y() + 2 * DLG_INPUT_HEIGHT + DLG_BUTTON_HEIGHT +
		      4 * DLG_BORDER, PROMPT_WIDTH, DLG_INPUT_HEIGHT,
		      _("Date:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_BOTTOM | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    m_pDate =
	new Fl_Input(x() + PROMPT_WIDTH + PROMPT_BORDER,
		     y() + 2 * DLG_INPUT_HEIGHT + DLG_BUTTON_HEIGHT +
		     4 * DLG_BORDER, DATE_INPUT_WIDTH, DLG_INPUT_HEIGHT);
    m_pDate->maximum_size(10);
    m_pDateButton =
	new Fl_Button(x() + PROMPT_WIDTH + DATE_INPUT_WIDTH +
		      2 * PROMPT_BORDER,
		      y() + 2 * DLG_INPUT_HEIGHT + DLG_BUTTON_HEIGHT +
		      4 * DLG_BORDER, IMAGE_BUTTON_WIDTH,
		      IMAGE_BUTTON_HEIGHT);
    m_pCalendarPixmap = Images::GetCalendarIcon();
    m_pCalendarPixmap->label(m_pDateButton);
    m_pDateButton->callback(DateButtonCallback);
    m_pDayOfWeek =
	new Fl_Output(x() + PROMPT_WIDTH + DATE_INPUT_WIDTH +
		      IMAGE_BUTTON_WIDTH + 3 * PROMPT_BORDER,
		      y() + 2 * DLG_INPUT_HEIGHT + DLG_BUTTON_HEIGHT +
		      4 * DLG_BORDER,
		      w() - PROMPT_WIDTH - DATE_INPUT_WIDTH -
		      IMAGE_BUTTON_WIDTH - 3 * PROMPT_BORDER,
		      DLG_INPUT_HEIGHT, "");
    m_pDayOfWeek->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
    m_pDayOfWeek->color(FL_GRAY);
    m_pDayOfWeek->textsize((4 * labelsize()) / 5);
    m_pDayOfWeek->textfont(FL_HELVETICA_BOLD);
    pBox = new Fl_Box(x(),
		      y() + 3 * DLG_INPUT_HEIGHT + 1 * DLG_BUTTON_HEIGHT +
		      5 * DLG_BORDER, PROMPT_WIDTH, DLG_BUTTON_HEIGHT,
		      _("Category:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    m_pCategoryChoice =
	new Fl_Choice(x() + PROMPT_WIDTH + PROMPT_BORDER,
		      y() + 3 * DLG_INPUT_HEIGHT + 1 * DLG_BUTTON_HEIGHT +
		      5 * DLG_BORDER, w() - PROMPT_WIDTH, DLG_BUTTON_HEIGHT);
    m_pCategoryMenu =
	ToDoListCategoryDB::GetToDoListCategoryDB()->GetCategoryMenu(false);
    m_pCategoryChoice->menu(m_pCategoryMenu);
    pBox = new Fl_Box(x(),
		      y() + 3 * DLG_INPUT_HEIGHT + 2 * DLG_BUTTON_HEIGHT +
		      6 * DLG_BORDER, PROMPT_WIDTH, DLG_BUTTON_HEIGHT,
		      _("Description:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    m_pDesc =
	new Fl_Output(x() + PROMPT_WIDTH + PROMPT_BORDER,
		      y() + 3 * DLG_INPUT_HEIGHT + 2 * DLG_BUTTON_HEIGHT +
		      6 * DLG_BORDER,
		      w() - PROMPT_WIDTH - IMAGE_BUTTON_WIDTH -
		      2 * PROMPT_BORDER, DLG_INPUT_HEIGHT);
    m_pDesc->color(FL_GRAY);
    m_pNoteButton = new Fl_Button(x() + w() - IMAGE_BUTTON_WIDTH,
				  y() + 3 * DLG_INPUT_HEIGHT +
				  2 * DLG_BUTTON_HEIGHT + 6 * DLG_BORDER,
				  IMAGE_BUTTON_WIDTH, IMAGE_BUTTON_HEIGHT);
    m_pNotePixmap = Images::GetNotesIcon();
    m_pNotePixmap->label(m_pNoteButton);
    m_pNoteButton->callback(NoteButtonCallback);
    pBox = new Fl_Box(x(),
		      y() + 4 * DLG_INPUT_HEIGHT + 2 * DLG_BUTTON_HEIGHT +
		      7 * DLG_BORDER, PROMPT_WIDTH, DLG_BUTTON_HEIGHT,
		      _("Complete:"));
    pBox->
	align(FL_ALIGN_RIGHT | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_WRAP);
    m_pCompleteButton =
	new Fl_Check_Button(x() + PROMPT_WIDTH + PROMPT_BORDER,
			    y() + 4 * DLG_INPUT_HEIGHT +
			    2 * DLG_BUTTON_HEIGHT + 7 * DLG_BORDER,
			    IMAGE_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
    m_pCompleteButton->down_box(FL_ROUND_DOWN_BOX);
    m_pApplyButton =
	new Fl_Button(x() + w() - DLG_BUTTON_WIDTH - PROMPT_BORDER,
		      y() + 4 * DLG_INPUT_HEIGHT + 3 * DLG_BUTTON_HEIGHT +
		      8 * DLG_BORDER, DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT,
		      _("&Apply"));
    m_pApplyButton->callback(OnApply);
    m_pApplyButton->deactivate();
    end();

    // Set that nothing is resizable
    resizable(new Fl_Box(0, y() + h() - 1, 1, 1));

    // Set that no item is being displayed
    m_nID = -1;
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
ToDoListDetails::~ToDoListDetails()
{
    FreeTranslatedMenu(m_pCategoryMenu);
    delete m_pCalendarPixmap;
    delete m_pNotePixmap;
}


//--------------------------------------------------------------//
// The completed flag has been changed in the list, change in   //
// the details if needed.                                       //
//--------------------------------------------------------------//
void
ToDoListDetails::ChangeComplete(int nRow, int nComplete)
{
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();

    if (pToDoListDB->GetID(nRow) == m_nID) {
	m_pCompleteButton->value(nComplete);
    }
}


//--------------------------------------------------------------//
// The due date/date completed has been changed in the list,    //
// change in the details if needed.                             //
//--------------------------------------------------------------//
void
ToDoListDetails::ChangeTime(int nRow, time_t nTime)
{
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();

    if (pToDoListDB->GetID(nRow) == m_nID) {
	m_pDate->value(::FormatDate(nTime).c_str());
	m_nDate = nTime;
	m_pDayOfWeek->value(::FormatDayOfWeek(m_nDate).c_str());
    }
}


//--------------------------------------------------------------//
// Process a click on the date button                           //
//--------------------------------------------------------------//
void
ToDoListDetails::DateButtonCallback(Fl_Widget * pWidget, void *pUserData)
{
    DatePickerDlg *pDlg;
    time_t nStartDate = time(NULL);
    ToDoListDetails *pThis =
	reinterpret_cast < ToDoListDetails * >(pWidget->parent());

    // Invoke the date picker dialog
    if (pThis->m_nDate < 24 * 60 * 60) {
	nStartDate = NormalizeDate(time(NULL));
    } else {
	nStartDate = pThis->m_nDate;
    }

    pDlg =
	new DatePickerDlg(nStartDate, DatePicker::Daily,
			  PixilDT::GetApp()->GetMainWindow());
    if (pDlg->DoModal() == 1) {
	pThis->m_nDate = pDlg->GetDate();
	pThis->m_pDate->value(::FormatDate(pThis->m_nDate).c_str());
	pThis->m_pDayOfWeek->value(::FormatDayOfWeek(pThis->m_nDate).c_str());
    }
    // Clean up
    delete pDlg;
}


//--------------------------------------------------------------//
// Display a ToDo Item                                          //
//--------------------------------------------------------------//
void
ToDoListDetails::DisplayRow(int nRow, int nRows)
{
    int nCategoryNo;
    int nPrio;
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();

    // Enable everything if there are some rows
    if (nRow >= 0 && nRows > 0) {
	// Enable all input objects
	Enable(true);

	// Change the display if this is a different row in the data base
	if (pToDoListDB->GetID(nRow) != m_nID) {
	    // Save any outstanding changes
	    SaveChanges(true);

	    // Display this row
	    m_pTitle->value(pToDoListDB->GetTitle(nRow).c_str());

	    // Get the priority
	    nPrio = pToDoListDB->GetPriority(nRow);
	    if (nPrio < 0 || nPrio >= 5) {
		nPrio = 0;
	    }
	    m_pPriority[nPrio]->setonly();

	    // Set up the date
	    m_nDate = pToDoListDB->GetTime(nRow);
	    m_pDate->value(pToDoListDB->GetTimeString(nRow).c_str());
	    m_pDayOfWeek->value(::FormatDayOfWeek(m_nDate).c_str());

	    // Set the category
	    nCategoryNo =
		ToDoListCategoryDB::GetToDoListCategoryDB()->FindRow(CATID,
								     pToDoListDB->
								     GetCategory
								     (nRow));
	    if (nCategoryNo < 0) {
		// Fix for a bad category
		nCategoryNo = 0;
	    }
	    m_pCategoryChoice->value(nCategoryNo);

	    // Set the description (like a note)
	    m_pDesc->
		value(::
		      WrapText(pToDoListDB->GetDescription(nRow).c_str(),
			       m_pDesc->w() - 2 * Fl::box_dx(FL_DOWN_BOX),
			       m_pDesc).c_str());

	    // Set the completed flag
	    m_pCompleteButton->value(pToDoListDB->GetComplete(nRow) !=
				     0 ? 1 : 0);

	    // Note the key-id being displayed
	    m_nID = pToDoListDB->GetID(nRow);
	}
    } else {
	// Disable everything if there are no rows for the category choice
	Enable(false);
	m_nID = -1;
    }
}


//--------------------------------------------------------------//
// Enable or disable all input fields.                          //
//--------------------------------------------------------------//
void
ToDoListDetails::Enable(bool bEnable)
{
    int i;

    if (bEnable == true) {
	// Activate everything
	m_pApplyButton->activate();
	m_pNoteButton->activate();
	for (i = 0; i < 5; ++i) {
	    m_pPriority[i]->activate();
	}
	m_pCompleteButton->activate();
	m_pCategoryChoice->activate();
	m_pDate->activate();
	m_pDate->color(FL_WHITE);
	delete m_pCalendarPixmap;
	m_pCalendarPixmap = Images::GetCalendarIcon();
	m_pCalendarPixmap->label(m_pDateButton);
	m_pDateButton->activate();
	m_pTitle->activate();
	m_pTitle->color(FL_WHITE);
	delete m_pNotePixmap;
	m_pNotePixmap = Images::GetNotesIcon();
	m_pNotePixmap->label(m_pNoteButton);
    } else {
	// Deactivate everything
	m_pApplyButton->deactivate();
	m_pPriority[0]->setonly();
	for (i = 0; i < 5; ++i) {
	    m_pPriority[i]->deactivate();
	}
	m_pCompleteButton->value(0);
	m_pCompleteButton->deactivate();
	m_pCategoryChoice->value(0);
	m_pCategoryChoice->deactivate();
	m_pDate->value("");
	m_pDate->deactivate();
	m_pDate->color(FL_GRAY);
	m_nDate = 0;
	m_pDayOfWeek->value(::FormatDayOfWeek(m_nDate).c_str());
	delete m_pCalendarPixmap;
	m_pCalendarPixmap =
	    Images::GetDisabledImage(Images::DISABLED_CALENDAR_ICON);
	m_pCalendarPixmap->label(m_pDateButton);
	m_pDateButton->deactivate();
	m_pTitle->value("");
	m_pTitle->deactivate();
	m_pTitle->color(FL_GRAY);
	delete m_pNotePixmap;
	m_pNotePixmap = Images::GetDisabledImage(Images::DISABLED_NOTES);
	m_pNotePixmap->label(m_pNoteButton);
	m_pNoteButton->deactivate();
    }
}


//--------------------------------------------------------------//
// Process a message from the parent widget                     //
//--------------------------------------------------------------//
int
ToDoListDetails::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case -1:			// Not implemented yet
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Process a click on the Notes/Description button              //
//--------------------------------------------------------------//
void
ToDoListDetails::NoteButtonCallback(Fl_Widget * pWidget, void *pUserData)
{
    int nRow;
    Note *pNote;
    NoteEditorDlg *pDlg;
    ToDoListDetails *pThis =
	reinterpret_cast < ToDoListDetails * >(pWidget->parent());
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();

    // Invoke the Note Editor dialog
    pNote = new Note(pToDoListDB->GetColumnSize(TODO_DESC));
    nRow = pToDoListDB->FindRow(TODO_ID, pThis->m_nID);
    pNote->SetText(pToDoListDB->GetDescription(nRow).c_str());
    pDlg = new NoteEditorDlg(pNote, PixilDT::GetApp()->GetMainWindow());
    if (pDlg->DoModal() == 1) {
	// Save the changed note
	pNote = pDlg->GetNote();
	if (pNote->IsChanged() == true) {
	    pToDoListDB->SetDescription(nRow, pNote->GetText().c_str());
	    pToDoListDB->Save();

	    // Set the description (like a note)
	    pThis->m_pDesc->
		value(::
		      WrapText(pToDoListDB->GetDescription(nRow).c_str(),
			       pThis->m_pDesc->w() -
			       2 * Fl::box_dx(FL_DOWN_BOX),
			       pThis->m_pDesc).c_str());

	    // Tell everyone of the change, (DisplayRow in this class will not refresh due to same row being displayed)
	    PixilDT::GetApp()->GetMainWindow()->Notify(TODO_LIST_CHANGED, 0);
	}
    }
    // Clean up
    delete pNote;
    delete pDlg;
}


//--------------------------------------------------------------//
// Apply changed to a note                                      //
//--------------------------------------------------------------//
void
ToDoListDetails::OnApply(Fl_Widget * pWidget, void *pUserData)
{
    ToDoListDetails *pThis = (ToDoListDetails *) (pWidget->parent());

    // Save any changes without asking whether to do so or not
    pThis->SaveChanges(false);
}


//--------------------------------------------------------------//
// Process a newly entered date.  The entered date must be a    //
// valid date in YY/MM/DD or YYYY/MM/DD format.  If only one    //
// delimiter is found then the date is assumed to be in MM/DD   //
// format for the current year.                                 //
//--------------------------------------------------------------//
bool
ToDoListDetails::ProcessDate()
{
    bool bReturn;
    int nResult;

    // Test the date
    nResult =::ValidateDate(m_pDate->value(), m_nDate);

    // Determine the results of the validation
    if (nResult < 0) {
	fl_alert(_("The due/completed date is not a valid date:\n\n%s"),::
		 GetDateError(nResult));
	bReturn = false;
    } else {
	m_pDate->value(::FormatDate(m_nDate).c_str());
	bReturn = true;
    }

    return (bReturn);
}


//--------------------------------------------------------------//
// Save any changes to the current ToDo Item.  A return of 0    //
// indicates that the user bypassed saving outstanding changes. //
//--------------------------------------------------------------//
int
ToDoListDetails::SaveChanges(bool bAsk)
{
    int i;
    int nCategory;
    int nPrio;
    int nResult;
    int nReturn = 1;
    int nRow;
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();

    // Find the current row
    nRow = pToDoListDB->FindRow(TODO_ID, m_nID);
    if (nRow >= 0) {
	// Get the category id
	nCategory =
	    ToDoListCategoryDB::GetToDoListCategoryDB()->
	    GetCategoryID(m_pCategoryChoice->value());

	// Get the selected priority
	for (i = 0, nPrio = 0; i < 5; ++i) {
	    if (m_pPriority[i]->value() != 0) {
		nPrio = i;
		break;
	    }
	}

	// Has anything been changed (changes to description/TODO_DESC have already been written to disk using note processing)
	if (pToDoListDB->GetCategory(nRow) != nCategory
	    || pToDoListDB->GetComplete(nRow) != m_pCompleteButton->value()
	    || pToDoListDB->GetPriority(nRow) != nPrio
	    || strcmp(pToDoListDB->GetTitle(nRow).c_str(),
		      m_pTitle->value()) != 0
	    || strcmp(pToDoListDB->GetTimeString(nRow).c_str(),
		      m_pDate->value()) != 0) {
	    // Does the user want to save these changes
	    if (bAsk == true) {
		nResult =
		    fl_choice(_
			      ("Do you wish to save the changes to the To Do item:\n\n%s"),
			      fl_no, fl_yes, fl_cancel, m_pTitle->value());
		if (nResult == 1) {
		    // Yes button, indicate to save
		    nResult = 1;
		} else if (nResult == 0) {
		    // No button, indicate to not save
		    nResult = 0;
		} else		//if (nResult==2)
		{
		    // Cancel button, indicate no save and cancel the calling operation
		    nResult = 0;
		    nReturn = 0;
		}
	    } else {
		// Save without asking
		nResult = 1;
	    }

	    // Save the changes
	    if (nResult == 1) {
		// Validate the date string
		if (ProcessDate() == true) {
		    pToDoListDB->SetCategory(nRow, nCategory);
		    pToDoListDB->SetComplete(nRow,
					     m_pCompleteButton->value());
		    pToDoListDB->SetPriority(nRow, nPrio);
		    pToDoListDB->SetTitle(nRow, m_pTitle->value());
		    pToDoListDB->SetTime(nRow, m_nDate);
		    pToDoListDB->Save();

		    // OK button was pressed, refresh displays
		    PixilDT::GetApp()->GetMainWindow()->
			Notify(TODO_LIST_CHANGED, 0);
		} else {
		    // Date is not valid, cancel the calling process
		    nReturn = 0;
		}
	    }
	}
    }

    return (nReturn);
}

--- NEW FILE: InfoDB.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Base class for all Category database classes.                //
//--------------------------------------------------------------//
#include "config.h"
#include "InfoDB.h"
#include "InfoDBDef.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Pointer to the only one of these objects.                    //
//--------------------------------------------------------------//
InfoDB *
    InfoDB::m_pThis =
    NULL;


//--------------------------------------------------------------//
// Default info typess if this is a new data base.              //
//--------------------------------------------------------------//
const char *
    InfoDB::m_pszDefaultType[7] = {
    N_("Work"),
    N_("Home"),
    N_("Fax"),
    N_("Mobile"),
    N_("Pager"),
    N_("E-Mail"),
    N_("Web Page"),
};


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
InfoDB::InfoDB()
:  NxDbAccess("add_info", &iFile, iFields)
{
    // Init the database if needed
    Init();
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
InfoDB::~InfoDB()
{
    m_pThis = NULL;
}


//--------------------------------------------------------------//
// Get a pointer to an open data base.                          //
//--------------------------------------------------------------//
InfoDB *
InfoDB::GetInfo()
{
    if (m_pThis == NULL) {
	m_pThis = new InfoDB;
    }
    return (m_pThis);
}


//--------------------------------------------------------------//
// Initialize the database at open.                             //
//--------------------------------------------------------------//
void
InfoDB::Init()
{
    // Init the data base if needed
    if (NumRecs() == 0) {
	int i;
	int nRow;

	for (i = 0; i < 7; ++i) {
	    nRow = Insert(i);
	    SetInfoType(nRow, _(m_pszDefaultType[i]));
	}
	Save();
    }
}


//--------------------------------------------------------------//
// Insert a new row and set its key id.                         //
//--------------------------------------------------------------//
int
InfoDB::Insert(int nInfoID)
{
    int nRow = NxDbAccess::Insert();

    // Now set the key value requested by the caller
    SetColumn(nRow, INFOID, nInfoID);

    // Save this row so that an uninitialized key
    // is not left in the data base if the program fails
    Save();

    return (nRow);
}

--- NEW FILE: NxDbRow.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class Used to represent a row in an NxDB database.           //
//--------------------------------------------------------------//
#include "NxDbRow.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Default constructor.                                         //
//--------------------------------------------------------------//
NxDbRow::NxDbRow()
{
    m_bChanged = true;
    m_bDeleted = false;
    m_bNeedDelete = false;
    m_bNew = true;
    m_nRecordNumber = 0;
    m_iFlags = NxDb::NEW;
}


//--------------------------------------------------------------//
// Construct with field definitions                             //
//--------------------------------------------------------------//
NxDbRow::NxDbRow(field * pField)
{
    SetColumns(pField);

    m_nRecordNumber = 0;
    m_iFlags = NxDb::NEW;
}


//--------------------------------------------------------------//
// Construct from data base info.                               //
//--------------------------------------------------------------//
NxDbRow::NxDbRow(const string & strDbName,	// Construct from data base info
		 int nRow, NxDb * pNxDb)
{
    char szBuffer[MAXRECSIZ];
    field *pField;
    int i;
    string strCopy = strDbName;

    pField = pNxDb->GetField(strCopy);
    SetColumns(pField);

    /* Grab the record flags first */
    int test;

    pNxDb->GetFlags(strCopy, nRow, test);
    m_iFlags = test;

    // Preset to not deleted
    m_bDeleted = false;

    // Read data from database
    /* FIXME:  Can we detect new and changed records here too? */

    for (i = 0; pField[i].type != '\0'; ++i) {
	if (pNxDb->Extract(strCopy, nRow, i, szBuffer) == 0) {
	    // This is a deleted record
	    m_bDeleted = true;
	    break;
	}
	if (pField[i].type == 'c') {
	    szBuffer[pField[i].size] = '\0';	// Workaround to error in NxDb class Extract method
	}
	m_vField[i].SetStringValue(szBuffer);
    }

    // Set that the data has not been changed
    m_bChanged = false;
    m_bNeedDelete = false;
    m_bNew = false;

    // Set the record number
    m_nRecordNumber = nRow;
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
NxDbRow::~NxDbRow()
{
}


//--------------------------------------------------------------//
// Assignment operator                                          //
//--------------------------------------------------------------//
NxDbRow & NxDbRow::operator=(const NxDbRow & Other)
{
    if (this != &Other) {
	m_bChanged = Other.m_bChanged;
	m_bDeleted = Other.m_bDeleted;
	m_bNeedDelete = Other.m_bNeedDelete;
	m_bNew = Other.m_bNew;
	m_nRecordNumber = Other.m_nRecordNumber;
	m_vField = Other.m_vField;
	m_iFlags = Other.m_iFlags;
    }

    return (*this);
}


//--------------------------------------------------------------//
// Clear all columns in this row, set up for re-use of the row. //
//--------------------------------------------------------------//
void
NxDbRow::Clear()
{
    int i;
    int nMax = m_vField.size();

    // Output each field
    for (i = 0; i < nMax; ++i) {
	m_vField[i].Clear();
    }

    // Reset the status
    m_bChanged = true;
    m_bDeleted = false;
    m_bNeedDelete = false;
    m_bNew = true;

    if (!(m_iFlags & NxDb::NEW))
	m_iFlags = NxDb::CHANGED;
    else
	m_iFlags = NxDb::NEW;

}


//--------------------------------------------------------------//
// Create the binary record to be written to the data base.     //
// The caller must delete the returned memory from here.        //
//--------------------------------------------------------------//
unsigned char *
NxDbRow::CreateRecord(string & strDbName, NxDb * pNxDb)
{
    field *pField = pNxDb->GetField(strDbName);

    int i;
    int nMax = m_vField.size();
    int nRecSize = pNxDb->GetFilDes(strDbName)->recsiz;
    unsigned char *ucPtr;
    unsigned char *ucRecord = new unsigned char[nRecSize + 1];	// One extra for unused terminator

#ifdef WIN32
    // Clear the record
    memset(ucRecord, 0, nRecSize);
#endif

    // Output each field
    for (i = 0, ucPtr = ucRecord; i < nMax; ++i) {
	m_vField[i].Output(ucPtr + pField[i].offset);
    }

    return (ucRecord);
}


//--------------------------------------------------------------//
// Export this row to a delimited string.                       //
//--------------------------------------------------------------//
void
NxDbRow::Export(vector < string > &vExportString)
{
    int i;
    int nMax = m_vField.size();
    string strReturn;

    vExportString.clear();
    for (i = 0; i < nMax; ++i) {
	vExportString.push_back(m_vField[i].Export());
    }
}


//--------------------------------------------------------------//
// Import data to this row from a delimited string.             //
//--------------------------------------------------------------//
void
NxDbRow::Import(const vector < string > &vExportString)
{
    int nColumn;
    int nMax = vExportString.size();

    for (nColumn = 0; nColumn < nMax; ++nColumn) {
	m_vField[nColumn].SetStringValue(vExportString[nColumn].c_str());
    }
}


//--------------------------------------------------------------//
// Save this row to disk if needed                              //
//--------------------------------------------------------------//
bool
NxDbRow::Save(const string & strDbName, NxDb * pNxDb)
{
    bool bReturn = true;
    string strName = strDbName;
    unsigned char *m_ucRecord = NULL;

#ifndef DEBUG
    // The external record number must have been set
    assert(m_nRecordNumber > 0);
#endif

    if (m_bDeleted == false) {
	if (m_bNeedDelete == true) {
	    // Delete this record
	    pNxDb->DeleteRec(strName, m_nRecordNumber);
	    m_bDeleted = true;
	} else if (m_bNew == true) {
	    // Insert this record
	    m_ucRecord = CreateRecord(strName, pNxDb);
	    pNxDb->Insert(strName, (char *) m_ucRecord);
	    m_bChanged = false;
	    m_bNew = false;
	} else if (m_bChanged == true) {
	    m_ucRecord = CreateRecord(strName, pNxDb);
	    pNxDb->Edit(strName, m_nRecordNumber, (char *) m_ucRecord);
	    m_bChanged = false;
	}
	// Clean up
	delete[]m_ucRecord;
    }

    /* Get the real flags */
    pNxDb->GetFlags(strName, m_nRecordNumber, m_iFlags);

    return (bReturn);
}


//--------------------------------------------------------------//
// Set the value of a column                                    //
//--------------------------------------------------------------//
bool
NxDbRow::SetColumn(int nCol, const char *pszValue)
{
    bool bReturn;

#ifdef DEBUG
    // Must fit within this row
    assert(nCol < (int) m_vField.size() && nCol >= 0);
#endif

    bReturn = m_vField[nCol].SetValue(pszValue);
    m_bChanged |= bReturn;

    if (!m_iFlags)
	m_iFlags = NxDb::CHANGED;

    return (bReturn);
}


//--------------------------------------------------------------//
// Set the value of a column                                    //
//--------------------------------------------------------------//
bool
NxDbRow::SetColumn(int nCol, int nValue)
{
    bool bReturn;

#ifdef DEBUG
    // Must fix within this row
    assert(nCol < (int) m_vField.size() && nCol >= 0);
#endif

    bReturn = m_vField[nCol].SetValue(nValue);
    m_bChanged |= bReturn;

    if (!m_iFlags)
	m_iFlags = NxDb::CHANGED;
    
    return (bReturn);
}


//--------------------------------------------------------------//
// Set the field definitions for this row.                      //
//--------------------------------------------------------------//
void
NxDbRow::SetColumns(field * pField)
{
    int i;
    NxDbColumn column(NxDbColumn::DataTypeChar);

    m_vField.clear();
    for (i = 0; pField[i].type != '\0'; ++i) {
	column.SetType(pField[i].type, pField[i].size);
	m_vField.push_back(column);
    }

    // Set that the data is new
    m_bChanged = true;
    m_bDeleted = false;
    m_bNeedDelete = false;
    m_bNew = true;
}

void
NxDbRow::UpdateFlags(const string & strDbName, NxDb * pNxDb) {
  pNxDb->SetFlags(strDbName, m_nRecordNumber, NxDb::NONE);
}

  
  

--- NEW FILE: FLTKUtil.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// FLTK utilities.                                              //
//--------------------------------------------------------------//
#include "config.h"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <strstream>
#include <FL/fl_draw.H>
#include "FLTKUtil.h"

#include "VCMemoryLeak.h"


#ifdef WIN32
typedef unsigned long COLORREF;
#define COLOR_BTNSHADOW 16
#define COLOR_MENU       4
#define COLOR_3DSHADOW  COLOR_BTNSHADOW
extern "C"
{
    __declspec(dllimport) COLORREF __stdcall GetSysColor(int nIndex);
#define strcasecmp stricmp
}
#endif


#define LEADING 4		// From Fl_Menu.cxx


//--------------------------------------------------------------//
// Break a string into lines delimited by new line characters.  //
//--------------------------------------------------------------//
void
BreakLines(const char *pszText, vector < string > &vLine)
{
    char *pChr;
    string strData;

    // Clear the vector of strings
    vLine.clear();

    // Process each line
    while (*pszText != '\0') {
	// Get the next line
	pChr = strchr(pszText, '\n');
	strData = pszText;
	if (pChr == NULL) {
	    // Last line in the text
	    pszText += strlen(pszText);
	} else {
	    // Intermediate line
	    strData = strData.substr(0, pChr - pszText);
	    pszText = pChr + 1;
	}

	// Kill any trailing white space
	while (strData.length() > 0 && isspace(strData[strData.length() - 1])) {
	    strData = strData.substr(0, strData.length() - 1);
	}

	// Add this string to the vector
	vLine.push_back(strData);
    }
}


//--------------------------------------------------------------//
// Create a translated menu usable for an Fl_Choice widget.     //
//--------------------------------------------------------------//
Fl_Menu_Item *
CreateChoice(int nCount, const char *const *ppszText, bool bTranslateMenu)
{
    Fl_Menu_Item *pReturn;
    int i;

    // Create the menu
    pReturn = new Fl_Menu_Item[nCount + 1];
    memset(pReturn, 0, (nCount + 1) * sizeof(Fl_Menu_Item));
    for (i = 0; i < nCount; ++i) {
	// Use strdup so that FreeTranslatedMenu will work correctly
	if (bTranslateMenu == true) {
	    pReturn[i].text = strdup(_(ppszText[i]));
	} else {
	    // Special, menu is already translated, don't translate again
	    pReturn[i].text = strdup(ppszText[i]);
	}
    }
    return (pReturn);
}


//--------------------------------------------------------------//
// Run a modal dialog.  Returns 1 if the OK button pressed or 0 //
// if the Cancel button was pressed.                            //
//--------------------------------------------------------------//
int
DoModal(Fl_Window * pWindow, Fl_Button * pOKButton, Fl_Button * pCancelButton)
{
    // Set the window modal and show it
    pWindow->set_modal();
    pWindow->show();

    // Process until the window shuts down
    while (pWindow->shown()) {
	Fl::wait();
	for (;;) {
	    Fl_Widget *pWidget = Fl::readqueue();

	    if (pWidget == NULL) {
		break;
	    }
	    if (pWidget == pOKButton) {
		// Done
		return (1);
	    }
	    if (pWidget == pWindow || pWidget == pCancelButton) {
		return (0);
	    }
	}
    }
    return (0);
}


//--------------------------------------------------------------//
// Run a popup menu, first determine the size of the menu and   //
// from that its positioning based on the requested point.      //
// Then run the popup menu and return the 0-based selection     //
// number or -1 if nothing was selected.  Shortcuts in the menu //
// will be ignored (not even displayed).                        //
//--------------------------------------------------------------//
int
DoPopupMenu(const Fl_Menu_Item * pMenuItem, int nX, int nY)
{
    const Fl_Menu_Item *pSelection;
    Fl_Menu_Item *pTranslated;
    int nHeight = 0;
    int nItem;
    int nReturn;
    int nScreenHeight = Fl::h();
    int nScreenWidth = Fl::w();
    int nSize = pMenuItem->size();
    int nThisHeight;
    int nThisWidth;
    int nWidth = 0;

    // Get the maximum height and width for any item
    for (nItem = 0; nItem < nSize; ++nItem) {
	nThisWidth = pMenuItem[nItem].measure(&nThisHeight, NULL);
	if (nThisWidth > nWidth) {
	    nWidth = nThisWidth;
	}
	if (nThisHeight > nHeight) {
	    nHeight = nThisHeight;
	}
    }

    // Fix the height for the entire menu
    nHeight = (nHeight + LEADING) * (nSize - 1);

    // Determine the location of the menu
    if (nX + nWidth >= nScreenWidth) {
	nX = nScreenWidth - nWidth;
    }
    if (nY + nHeight >= nScreenHeight) {
	nY = nScreenHeight - nHeight;
    }
    // Now show the popup menu
    pTranslated = TranslateMenuItems(pMenuItem);
    pSelection = pTranslated->popup(nX, nY);
    nReturn = (pSelection != NULL ? pSelection - pTranslated : -1);
    FreeTranslatedMenu(pTranslated);
    return (nReturn);
}


//--------------------------------------------------------------//
// Free up a translated menu.                                   //
//--------------------------------------------------------------//
void
FreeTranslatedMenu(Fl_Menu_Item * pMenuItem)
{
    Fl_Menu_Item *pMenuItem2 = (Fl_Menu_Item *) pMenuItem;
    int nNest;

    // Free each string in the menu
    nNest = 0;
    while (nNest > 0 || pMenuItem2->text != NULL) {
	if (pMenuItem2->text != NULL) {
	    // These were allocated with strdup, so free (not delete) them
	    free((char *) pMenuItem2->text);
	}
	// Reset the nesting as needed
	if (pMenuItem2->text == NULL) {
	    // Reduce the nesting count
	    --nNest;
	} else if ((pMenuItem2->flags & FL_SUBMENU) != 0) {
	    // Increment the nesting
	    ++nNest;
	}
	// Go to the next menu item
	++pMenuItem2;
    }

    // Now free the entire menu (use delete [])
    delete[]pMenuItem;
}


//--------------------------------------------------------------//
// Get an FLTK color.                                           //
//--------------------------------------------------------------//
Fl_Color
GetFLTKColor(int nRGB)
{
    return (GetFLTKColor((nRGB >> 16), (nRGB >> 8), nRGB));
}


//--------------------------------------------------------------//
// Get an FLTK color.                                           //
//--------------------------------------------------------------//
Fl_Color
GetFLTKColor(int nRed, int nGreen, int nBlue)
{
    return (fl_color_cube((nRed & 0xff) * FL_NUM_RED / 256,
			  (nGreen & 0xff) * FL_NUM_GREEN / 256,
			  (nBlue & 0xff) * FL_NUM_BLUE / 256));
}


//--------------------------------------------------------------//
// Translate menu items using gettext.  The original menu is    //
// const so the entire menu is duplicated with the translated   //
// strings.                                                     //
//--------------------------------------------------------------//
Fl_Menu_Item *
TranslateMenuItems(const Fl_Menu_Item * pMenuItem)
{
    Fl_Menu_Item *pMenuItem2 = (Fl_Menu_Item *) pMenuItem;
    int i;
    int nCount = pMenuItem->size();

    // Allocate space for the new menu
    pMenuItem2 = new Fl_Menu_Item[ /*++ */ nCount];
    memcpy(pMenuItem2, pMenuItem, sizeof(Fl_Menu_Item) * nCount);

    // Now translate the strings in the new menu
    for (i = 0; i < nCount; ++i) {
	if (pMenuItem2[i].text != NULL) {
	    // Use strdup so that FreeTranslatedMenu will work correctly
	    pMenuItem2[i].text = strdup(_(pMenuItem2[i].text));
	}
    }

    return (pMenuItem2);
}


//--------------------------------------------------------------//
// Translate menu items using gettext.  The original menu is    //
// non-const so the menu is not copied, only the strings are    //
// replaced.                                                    //
//--------------------------------------------------------------//
Fl_Menu_Item *
TranslateMenuItems(Fl_Menu_Item * pMenuItem)
{
    const char *pszTranslated;
    int i;
    int nCount /* = 0 */ ;

    // Count the number of menu items to be translated
    nCount = pMenuItem->size();

    // Now translate the strings in the menu
    for (i = 0; i < nCount; ++i) {
	if (pMenuItem[i].text != NULL) {
	    pszTranslated = _(pMenuItem[i].text);
	    free((char *) pMenuItem[i].text);

	    // Use strdup so that FreeTranslatedMenu will work correctly
	    pMenuItem[i].text = strdup(pszTranslated);
	}
    }

    return (pMenuItem);
}


//--------------------------------------------------------------//
// Get the first part of a line of text.                        //
//--------------------------------------------------------------//
string
WrapText(const char *pszText, int nMaxWidth, Fl_Widget * pWidget)
{
    static const char *pszEllipsis = "...";
    char *pszBufEnd;
    char *pszBuffer;
    char *pszBuffer2;
    char *pszBufStart;
    const char *pszEnd;
    const char *pszEnd2;
    char *pszOldBufEnd;
    int i;
    int nChr;
    int nFlHeight;
    int nHeight;
    int nLength;
    int nMax;
    int nWidth;
    string strReturn;

    // Initialize the font for measurements
    fl_font(pWidget->labelfont(), pWidget->labelsize());
    nFlHeight = fl_height() + fl_descent();

    // Get a new-line delimited block of characters
    pszEnd = strchr(pszText, '\n');
    if (pszEnd == NULL) {
	pszEnd = pszText + strlen(pszText);
    }
    pszEnd2 = strchr(pszText, '\r');
    if (pszEnd2 == NULL) {
	pszEnd2 = pszText + strlen(pszText);
    }
    if (pszEnd2 < pszEnd) {
	pszEnd = pszEnd2;
    }
    // Will this line fit into the length allowed
    nLength = pszEnd - pszText + 1;
    pszBuffer = new char[nLength];
    strncpy(pszBuffer, pszText, nLength - 1);
    pszBuffer[nLength - 1] = '\0';
    pszBufStart = pszBuffer;
    while (*pszBufStart == ' ') {
	++pszBufStart;
    }
    nWidth = nMaxWidth;
    fl_measure(pszBufStart, nWidth, nHeight);

    // Break out a smaller portion of the line if needed
    if (nHeight >= nFlHeight || nWidth > nMaxWidth) {
	// Get the width of an ellipsis that will be added to the end of the text
	fl_measure(pszEllipsis, nWidth, nHeight);
	if (nMaxWidth >= 2 * nWidth) {
	    nMaxWidth -= nWidth;
	}
	// Find a small enough portion of this line to fit
	pszBufEnd = pszBufStart;
	do {
	    pszOldBufEnd = pszBufEnd;
	    pszBufEnd = strchr(pszBufEnd + 1, ' ');
	    if (pszBufEnd == NULL) {
		// Too long a word at the end of the line
		break;
	    }
	    *pszBufEnd = '\0';
	    nWidth = nMaxWidth;
	    fl_measure(pszBufStart, nWidth, nHeight);
	    *pszBufEnd = ' ';
	} while (nHeight == nFlHeight && nWidth <= nMaxWidth);

	// Output the first portion of the remaining line
	if (pszOldBufEnd == pszBufStart) {
	    // Word too long, just output characters
	    nMax = strlen(pszBufStart) - 1;
	    nWidth = nMaxWidth + 1;
	    for (i = nMax;
		 i > 1 && (nHeight > nFlHeight || nWidth > nMaxWidth); --i) {
		nChr = pszBufStart[i];
		pszBufStart[i] = '\0';
		nWidth = nMaxWidth;
		fl_measure(pszBufStart, nWidth, nHeight);
		pszBufStart[i] = nChr;
	    }

	    // Get these characters and set up to return them
	    if (i < 0) {
		i = 0;
	    }
	    pszBuffer2 = new char[i + 3 + 1];
	    strncpy(pszBuffer2, pszBufStart, i);
	    pszBuffer2[i] = '\0';
	} else {
	    // Can break at white space (blank)
	    i = pszOldBufEnd - pszBufStart;
	    pszBuffer2 = new char[i + 3 + 1];
	    strncpy(pszBuffer2, pszBufStart, i);
	    while (i >= 0 && pszBuffer2[i] == ' ') {
		--i;
	    }
	    pszBuffer2[i] = '\0';
	}

	// Add an ellipsis to the end of the text
	strcat(pszBuffer2, pszEllipsis);
    } else {
	// Just use the buffer as is
	pszBuffer2 = new char[strlen(pszBuffer) + 1];
	strcpy(pszBuffer2, pszBuffer);
    }

    // Clean up
    delete[]pszBuffer;
    strReturn = pszBuffer2;
    delete[]pszBuffer2;
    return (strReturn);
}

--- NEW FILE: CustomFieldDB.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Base class for all Category database classes.                //
//--------------------------------------------------------------//
#include "config.h"
#include "CustomFieldDB.h"
#include "CustomFieldDBDef.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Pointer to the only one of these objects.                    //
//--------------------------------------------------------------//
CustomFieldDB *
    CustomFieldDB::m_pThis =
    NULL;


//--------------------------------------------------------------//
// Default info typess if this is a new data base.              //
//--------------------------------------------------------------//
const char *
    CustomFieldDB::m_pszDefaultName[4] = {
    N_("Custom1"),
    N_("Custom2"),
    N_("Custom3"),
    N_("Custom4"),
};


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
CustomFieldDB::CustomFieldDB()
:  NxDbAccess("add_custfields", &custFile, custFields)
{
    // Init the database if needed
    Init();
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
CustomFieldDB::~CustomFieldDB()
{
    m_pThis = NULL;
}


//--------------------------------------------------------------//
// Get a pointer to an open data base.                          //
//--------------------------------------------------------------//
CustomFieldDB *
CustomFieldDB::GetCustomField()
{
    if (m_pThis == NULL) {
	m_pThis = new CustomFieldDB;
    }
    return (m_pThis);
}


//--------------------------------------------------------------//
// Initialize the database at open.                             //
//--------------------------------------------------------------//
void
CustomFieldDB::Init()
{
    // Init the data base if needed
    if (NumRecs() == 0) {
	int i;
	int nRow;

	for (i = 0; i < 4; ++i) {
	    nRow = Insert(i);
	    SetName(nRow, _(m_pszDefaultName[i]));
	}
	Save();
    }
}


//--------------------------------------------------------------//
// Insert a new row and set its key id.                         //
//--------------------------------------------------------------//
int
CustomFieldDB::Insert(int nID)
{
    int nRow = NxDbAccess::Insert();

    // Now set the key value requested by the caller
    SetColumn(nRow, CUSTOMID, nID);

    return (nRow);
}

--- NEW FILE: ScheduleEvent.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Schedule Event widget                                        //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_draw.H>
#include <FL/forms.H>

#include "Dialog.h"
#include "FLTKUtil.h"
#include "Images.h"
#include "PixilDT.h"
#include "SchedulerChangeTypeDlg.h"
#include "ScheduleEvent.h"
#include "SchedulerDB.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
ScheduleEvent::ScheduleEvent(int nX,
			     int nY,
			     int nWidth,
			     int nHeight,
			     int nHourHeight, int nRow, time_t nDate)
    :
Fl_Box(nX, nY, nWidth, nHeight)
{
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();

#ifdef DEBUG
    assert(nDate ==::NormalizeDate(nDate));	// Must be a normalized date
#endif

    // Save the row number in the SchedulerDB
    m_nRow = nRow;

    // Save the width and height of this widget
    m_nHeight = nHeight;
    m_nWidth = nWidth;

    // Save the height of an hour in this widget
    m_nHourHeight = nHourHeight;

    // Get the date for this event
    m_nDate = nDate;

    // Set that no repeating pixmap has been used yet
    m_pPixmap = NULL;

    // Get the label for this widget
    m_strLabel = pSchedulerDB->GetDescription(nRow);
    m_strLabel =::WrapText(m_strLabel.c_str(), w() - 2 * DLG_BORDER, this);
    label(m_strLabel.c_str());
    align(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE);

    // Set other parameters
    box(FL_BORDER_BOX);
    color(FL_YELLOW);

    // Set the state of this widget
    m_bResizing = false;
    m_bMoving = false;
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
ScheduleEvent::~ScheduleEvent()
{
    delete m_pPixmap;
}


//--------------------------------------------------------------//
// Draw this Event                                              //
//--------------------------------------------------------------//
void
ScheduleEvent::draw()
{
    bool bRepeats;
    Fl_Label labelIcon;
    Fl_Label labelText;
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();

    // Redraw everything every time
    color(Fl::focus() == this ? FL_WHITE : FL_YELLOW);
    fl_color(color());
    draw_box();

    // If in focus, draw a heavy lower border
    fl_color(FL_BLACK);
    if (Fl::focus() == this) {
	fl_color(FL_BLACK);
	fl_rectf(x(), y() + h() - EVENT_BORDER, w() - 1, EVENT_BORDER - 1);
    }
    // Always draw the right hand border
    fl_color(FL_BLUE);
    fl_rectf(x() + w() - EVENT_BORDER, y() + 1, EVENT_BORDER - 1,
	     m_nHeight - 1);

    // Fix up the label in case the width has changed
    m_strLabel = pSchedulerDB->GetDescription(m_nRow);
    bRepeats = pSchedulerDB->GetRepeatingFlag(m_nRow);
    m_strLabel =::WrapText(m_strLabel.c_str(),
			   w() - DLG_BORDER - EVENT_BORDER - labelsize() -
			   (bRepeats ? labelsize() : 0), this);

    // Draw the repeating icon if needed
    if (bRepeats == true) {
	if (m_pPixmap == NULL) {
	    m_pPixmap = Images::GetRepeatIcon();
	}
	m_pPixmap->label(this);	// Sets up various static things in Fl_Pixmap.cxx
	labelIcon.value = (const char *) m_pPixmap;
	labelIcon.type = _FL_PIXMAP_LABEL;
	labelIcon.font = FL_HELVETICA;
	labelIcon.size = FL_NORMAL_SIZE;
	labelIcon.color = FL_BLACK;
	labelIcon.draw(x() + Fl::box_dx(box()),
		       y() + Fl::box_dy(box()) + 2,
		       labelsize(), h() - Fl::box_dh(box()), align());
    }
    // Draw the text label manually
    labelText.value = m_strLabel.c_str();
    labelText.type = FL_NORMAL_LABEL;
    labelText.font = FL_HELVETICA;
    labelText.size = FL_NORMAL_SIZE;
    labelText.color = FL_BLACK;
    labelText.draw(x() + Fl::box_dx(box()) +
		   (bRepeats ? labelsize() : labelsize() / 2),
		   y() + Fl::box_dy(box()),
		   w() - Fl::box_dw(box()) - (bRepeats ? 1 : 2) * labelsize(),
		   h() - Fl::box_dh(box()), align());
}


//--------------------------------------------------------------//
// Handle events for this widget                                //
//--------------------------------------------------------------//
int
ScheduleEvent::handle(int nEvent)
{
    int nReturn = Fl_Box::handle(nEvent);

    switch (nEvent) {
    case FL_PUSH:
	// Set this widget up for dragging if the click is in the correct part
	if (Fl::event_button() == FL_LEFT_MOUSE) {
	    if (Fl::focus() == this) {
		// This widget is in focus, test where the click occurred
		if (Fl::event_x() > x() + w() - EVENT_BORDER - 1
		    && Fl::event_x() < x() + w()) {
		    // Get ready to move
		    m_bMoving = true;
		    m_nX = x();
		    m_nY = y();
		    m_nOriginalX = Fl::event_x();
		    m_nOriginalY = Fl::event_y();

		    // Get the schedule container's scroll position
		    m_nOriginalScrollY =
			((Fl_Scroll *) (parent()->parent()->parent()))->
			yposition();
		} else if (Fl::event_y() > y() + h() - EVENT_BORDER - 1
			   && Fl::event_y() < y() + h()) {
		    // Get ready to resize
		    m_bResizing = true;
		    m_nOriginalHeight = m_nHeight;
		    m_nOriginalY = Fl::event_y();
		}
	    } else {
		// Accept a click on the right border for moving even if not in focus
		if (Fl::event_x() > x() + w() - EVENT_BORDER - 1
		    && Fl::event_x() < x() + w()) {
		    // Get ready to move
		    m_bMoving = true;
		    m_nX = x();
		    m_nY = y();
		    m_nOriginalX = Fl::event_x();
		    m_nOriginalY = Fl::event_y();

		    // Get the schedule container's scroll position
		    m_nOriginalScrollY =
			((Fl_Scroll *) (parent()->parent()->parent()))->
			yposition();
		}
	    }

	    // Use the keyboard focus to indicate that this widget is currently selected
	    Fl::focus(this);
	    ((ScheduleDay *) parent())->insert(*this, (Fl_Widget *) NULL);

	    // Notify the parent of the selection
	    ((ScheduleDay *) parent())->SetSelectedItem(m_nRow);

	    // Expand this widget and change the color
	    h(m_nHeight + EVENT_BORDER);
	    color(FL_WHITE);

	    // Redraw this widget
	    redraw();
	    nReturn = 1;
	} else if (Fl::event_button() == FL_RIGHT_MOUSE) {
	    // Right mouse - show an edit menu
	    RightMouse();
	}
	break;

    case FL_RELEASE:
	// If resizing, drop it here
	if (m_bResizing == true) {
	    ResizeDrop();
	} else if (m_bMoving == true) {
	    MoveDrop();
	}
	nReturn = 1;
	break;

    case FL_ENTER:
	nReturn = 1;
	break;

    case FL_LEAVE:
	// Reset to a normal cursor
	PixilDT::GetApp()->GetMainWindow()->ResetCursor();
	break;

    case FL_MOVE:
	if (Fl::focus() == this) {
	    // Change to a move/resize cursor if needed
	    if (Fl::event_x() > x() + w() - EVENT_BORDER - 1
		&& Fl::event_x() < x() + w()) {
		PixilDT::GetApp()->GetMainWindow()->SetCursor(FL_CURSOR_MOVE);
	    } else if (Fl::event_y() > y() + h() - EVENT_BORDER - 1
		       && Fl::event_y() < y() + h()) {
		PixilDT::GetApp()->GetMainWindow()->SetCursor(FL_CURSOR_NS);
	    } else {
		PixilDT::GetApp()->GetMainWindow()->ResetCursor();
	    }
	} else {
	    // Change to a move cursor even if not in focus
	    if (Fl::event_x() > x() + w() - EVENT_BORDER - 1
		&& Fl::event_x() < x() + w()) {
		PixilDT::GetApp()->GetMainWindow()->SetCursor(FL_CURSOR_MOVE);
	    } else {
		PixilDT::GetApp()->GetMainWindow()->ResetCursor();
	    }
	}
	nReturn = 1;
	break;

    case FL_DRAG:
	// If resizing, change the size now
	if (m_bResizing == true) {
	    Resize();
	} else if (m_bMoving == true) {
	    Move();
	}
	break;

    case FL_FOCUS:
	// Always refuse the focus
	nReturn = 0;
	break;

    case FL_UNFOCUS:
	// If resizing, drop it here
	if (m_bResizing == true) {
	    ResizeDrop();
	} else if (m_bMoving == true) {
	    MoveDrop();
	}
	// Reset to the original size
	size(m_nWidth, m_nHeight);
	color(FL_YELLOW);
	parent()->redraw();

	nReturn = 1;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Move this widget during a drag operation.                    //
//--------------------------------------------------------------//
void
ScheduleEvent::Move()
{
    int nChangeX;
    int nChangeY;
    int nX;
    int nY;

    // Calculate the movement change so far
    nChangeX = Fl::event_x() - m_nOriginalX;
    nChangeY = Fl::event_y() - m_nOriginalY;

    // Is the new position out of range
    nX = m_nX + nChangeX;
    if (nX < parent()->x()) {
	nX = parent()->x();
    }
    if (nX > parent()->x() + parent()->w() - 1 - w()) {
	nX = parent()->x() + parent()->w() - 1 - w();
    }
    nY = m_nY + nChangeY;
    if (nY < parent()->y()) {
	nY = parent()->y();
    }
    if (nY > parent()->y() + parent()->h() - 1 - h()) {
	nY = parent()->y() + parent()->h() - 1 - h();
    }
    // Move the widget
    position(nX, nY);
    parent()->damage(FL_DAMAGE_ALL);
}


//--------------------------------------------------------------//
// Drop a move operation.                                       //
//--------------------------------------------------------------//
void
ScheduleEvent::MoveDrop()
{
    int nContinue;
    int nNewRow;
    int nScrollPosition =
	((Fl_Scroll *) (parent()->parent()->parent()))->yposition();
    int nStart;
    int nY;
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();
    time_t nStartTime;

    // Move this widget one last time
    Move();

    // Calculate the Y-offset based on the scrolling position
    nY = y() + nScrollPosition - (parent()->parent()->parent())->y();

    // Now round its start time to the nearest half hour
    nStart = (2 * nY + ((m_nHourHeight - 1) >> 1)) / m_nHourHeight;

    // Reset to the original size
    size(m_nWidth, m_nHeight);
    color(FL_YELLOW);

    // Turn off moving
    m_bMoving = false;

    // If this is a repeating event, ask about which instances to change
    if (pSchedulerDB->GetRepeatingFlag(m_nRow) == true) {
	SchedulerChangeTypeDlg *pDlg =
	    new SchedulerChangeTypeDlg(this, false);

	pDlg->DoModal();
	nContinue = pDlg->GetChangeType();
	delete pDlg;
    } else {
	nContinue = SCHEDULER_CHANGE_TYPE_ALL;
    }

    switch (nContinue) {
    case SCHEDULER_CHANGE_TYPE_ALL:
	// Move this event
	pSchedulerDB->MoveStartTime(m_nRow, nStart * 30 * 60);
	break;

    case SCHEDULER_CHANGE_TYPE_CURRENT_FUTURE:
	// Add a new row to carry on from here
	nNewRow = pSchedulerDB->CopyRow(m_nRow);

	// Make these repetitions end one day prior to the selected event
	pSchedulerDB->EndRepetitions(m_nRow,::SubtractDays(m_nDate, 1));

	// Now fix the new row
	nStartTime = pSchedulerDB->GetStartTime(nNewRow);
	nStartTime = nStartTime -::NormalizeDate(nStartTime);
	pSchedulerDB->SetStartDate(nNewRow, m_nDate, nStartTime);
	pSchedulerDB->MoveStartTime(nNewRow, nStart * 30 * 60);
	break;

    case SCHEDULER_CHANGE_TYPE_CURRENT_ONLY:
	// Add a new row for this exception date
	nNewRow = pSchedulerDB->CopyRow(m_nRow);

	// Add a deleted exception for this date
	pSchedulerDB->AddDeletedException(m_nRow, m_nDate);

	// Now fix the new row
	nStartTime = pSchedulerDB->GetStartTime(nNewRow);
	nStartTime = nStartTime -::NormalizeDate(nStartTime);
	pSchedulerDB->SetStartDate(nNewRow, m_nDate, nStartTime);
	pSchedulerDB->SetNoRepetition(nNewRow);
	pSchedulerDB->MoveStartTime(nNewRow, nStart * 30 * 60);
    }

    // Save the changes to the scheduler data base
    pSchedulerDB->Save();

    // Notify everyone of the changes, will refresh this widget also
    PixilDT::GetApp()->GetMainWindow()->Notify(SCHEDULER_CHANGED, 0);

    // Reset to a normal cursor
    PixilDT::GetApp()->GetMainWindow()->ResetCursor();
}


//--------------------------------------------------------------//
// Catch a resize operation and save the height and width.      //
//--------------------------------------------------------------//
void
ScheduleEvent::resize(int nX, int nY, int nWidth, int nHeight)
{
    m_nWidth = nWidth;
    m_nHeight = nHeight;
    Fl_Box::resize(nX, nY, nWidth, nHeight);
}


//--------------------------------------------------------------//
// Resize this widget during a drag operation.                  //
//--------------------------------------------------------------//
void
ScheduleEvent::Resize()
{
    int nChange;
    int nOldHeight;

    // Calculate the height change so far
    nChange = Fl::event_y() - m_nOriginalY;

    // Is the duration too small
    m_nHeight = m_nOriginalHeight + nChange;
    if (m_nHeight < (m_nHourHeight >> 1)) {
	m_nHeight = (m_nHourHeight >> 1);
    }
    // Resize the widget
    nOldHeight = h();
    damage_resize(x(), y(), w(), m_nHeight + EVENT_BORDER);

    // Needed or the widget will not re-draw correctly (why?)
    if (nOldHeight > m_nHeight) {
	parent()->damage(FL_DAMAGE_ALL);
    }
}


//--------------------------------------------------------------//
// Drop a resize operation.                                     //
//--------------------------------------------------------------//
void
ScheduleEvent::ResizeDrop()
{
    int nContinue;
    int nDuration;
    int nNewRow;
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();
    time_t nStartTime;

    // Resize this widget one last time
    Resize();
    damage(FL_DAMAGE_ALL);

    // Now round its end time to the nearest half hour
    nDuration = (2 * h() + ((m_nHourHeight - 1) >> 1)) / m_nHourHeight;

    // Reset the height of this widget
    m_nHeight = ((nDuration * m_nHourHeight) >> 1);
    h(m_nHeight);

    // Reset to the original size
    size(m_nWidth, m_nHeight);
    color(FL_YELLOW);

    // Turn off resizing
    m_bResizing = false;

    // If this is a repeating event, ask about which instances to change
    if (pSchedulerDB->GetRepeatingFlag(m_nRow) == true) {
	SchedulerChangeTypeDlg *pDlg =
	    new SchedulerChangeTypeDlg(this, false);

	pDlg->DoModal();
	nContinue = pDlg->GetChangeType();
	delete pDlg;
    } else {
	nContinue = SCHEDULER_CHANGE_TYPE_ALL;
    }

    switch (nContinue) {
    case SCHEDULER_CHANGE_TYPE_ALL:
	// Resize this event
	pSchedulerDB->SetRoundedDuration(m_nRow, nDuration * 30 * 60);
	break;

    case SCHEDULER_CHANGE_TYPE_CURRENT_FUTURE:
	// Add a new row to carry on from here
	nNewRow = pSchedulerDB->CopyRow(m_nRow);

	// Make these repetitions end one day prior to the selected event
	pSchedulerDB->EndRepetitions(m_nRow,::SubtractDays(m_nDate, 1));

	// Now fix the new row
	nStartTime = pSchedulerDB->GetStartTime(nNewRow);
	nStartTime = nStartTime -::NormalizeDate(nStartTime);
	pSchedulerDB->SetStartDate(nNewRow, m_nDate, nStartTime);
	pSchedulerDB->SetRoundedDuration(nNewRow, nDuration * 30 * 60);
	break;

    case SCHEDULER_CHANGE_TYPE_CURRENT_ONLY:
	// Add a new row for this exception date
	nNewRow = pSchedulerDB->CopyRow(m_nRow);

	// Add a deleted exception for this date
	pSchedulerDB->AddDeletedException(m_nRow, m_nDate);

	// Now fix the new row
	nStartTime = pSchedulerDB->GetStartTime(nNewRow);
	nStartTime = nStartTime -::NormalizeDate(nStartTime);
	pSchedulerDB->SetStartDate(nNewRow, m_nDate, nStartTime);
	pSchedulerDB->SetNoRepetition(nNewRow);
	pSchedulerDB->SetRoundedDuration(nNewRow, nDuration * 30 * 60);
    }

    // Save the changes to the scheduler data base
    pSchedulerDB->Save();

    // If an actual change then notify everyone of the changes
    PixilDT::GetApp()->GetMainWindow()->Notify(SCHEDULER_CHANGED, 0);

    // Reset to a normal cursor
    PixilDT::GetApp()->GetMainWindow()->ResetCursor();
}


//--------------------------------------------------------------//
// Handle a right mouse click.                                  //
//--------------------------------------------------------------//
void
ScheduleEvent::RightMouse()
{
    static const Fl_Menu_Item menuPopup[] = {
	{N_("Delete Appointment")},
	{N_("Edit Appointment"), 0, 0, 0, FL_MENU_DIVIDER},
	{N_("New Appointment")},
	{NULL},
    };
    int nSelection;

    // Display the popup menu
    nSelection = DoPopupMenu(menuPopup, Fl::event_x(), Fl::event_y());

    if (nSelection >= 0) {
	// Process the selection
	switch (nSelection) {
	case 0:		// Delete this row
	    ((ScheduleDay *) parent())->Delete(m_nRow);
	    break;

	case 1:		// Edit this row
	    ((ScheduleDay *) parent())->Edit(m_nRow);
	    break;

	case 2:		// Insert a new row
	    ((ScheduleDay *) parent())->EditNew(m_nDate);
	}
    }
}

--- NEW FILE: ToDoListList.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
[...1025 lines suppressed...]
		bReturn = false;
	    } else if (nValue1 < nValue2) {
		bReturn = true;
	    } else {
		bReturn =
		    (pRow1->GetIntValue(TODO_TIME) <
		     pRow2->GetIntValue(TODO_TIME));
	    }
	    break;

	default:
#ifdef DEBUG
	    assert(false);	// Unknown sort algorithm
#endif
	    bReturn = false;
	}
    }

    return (bReturn);
}

--- NEW FILE: OptionsDlg.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Options Dialog.                                              //
//--------------------------------------------------------------//
#include "config.h"
#include <FL/fl_message.H>
#include <FL/Fl_Return_Button.H>
#include "OptionsDlg.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "HelpID.h"
#include "InputBox.h"
#include "Options.h"
#include "PixilDT.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


#ifdef WIN32
#define max __max
#define min __min
#endif


#define CHOICE_WIDTH 150
#define PROMPT_WIDTH 150
#define TAB_HEIGHT   DLG_BUTTON_HEIGHT
#define DLG_HEIGHT   (6*DLG_BORDER+4*DLG_BUTTON_HEIGHT+DLG_INPUT_HEIGHT+TAB_HEIGHT)
#define DLG_WIDTH    (5*DLG_BORDER+PROMPT_WIDTH+150+DLG_BUTTON_WIDTH)


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
OptionsDlg::OptionsDlg(Fl_Widget * pParent)
:  Fl_Window(pParent->x() + ((pParent->w() - DLG_WIDTH) >> 1),
	  pParent->y() + ((pParent->h() - DLG_HEIGHT) >> 1),
	  DLG_WIDTH, DLG_HEIGHT, _("Options"))
{
    static const char *pszApp[4] = {
	"Scheduler",
	"Address Book",
	"Notes",
	"ToDo List",
    };
    static const char *pszDay[2] = {
	"Sunday",
	"Monday",
    };
    char *pszHour[23];
    Fl_Group *pGroup;
    Fl_Tabs *pTabs;
    int i;
    int j;
    string strAM;
    string strPM;

    // Create the tab widget
    pTabs = new Fl_Tabs(DLG_BORDER,
			DLG_BORDER,
			w() - 2 * DLG_BORDER,
			h() - 3 * DLG_BORDER - DLG_BUTTON_HEIGHT);

    // Create the first page for the tab
    pGroup = new Fl_Group(2 * DLG_BORDER,
			  DLG_BORDER + TAB_HEIGHT,
			  w() - 4 * DLG_BORDER,
			  h() - 5 * DLG_BORDER - DLG_BUTTON_HEIGHT,
			  _("General"));
    m_pAppChoice = new Fl_Choice(2 * DLG_BORDER + PROMPT_WIDTH,
				 TAB_HEIGHT + 2 * DLG_BORDER,
				 CHOICE_WIDTH,
				 DLG_BUTTON_HEIGHT,
				 _("Startup Application:"));
    m_pMenuApp = CreateChoice(4, pszApp, true);
    m_pAppChoice->menu(m_pMenuApp);
    m_pAppChoice->value(Options::GetMainPage());
    m_pDataDir = new Fl_Input(2 * DLG_BORDER + PROMPT_WIDTH,
			      TAB_HEIGHT + 3 * DLG_BORDER + DLG_BUTTON_HEIGHT,
			      w() - 5 * DLG_BORDER - DLG_BUTTON_WIDTH -
			      PROMPT_WIDTH, DLG_INPUT_HEIGHT,
			      _("Data Directory:"));
    m_pDataDir->maximum_size(256);
    m_pDataDir->value(Options::GetDatabasePath().c_str());
    m_pBrowseButton = new Fl_Button(w() - 2 * DLG_BORDER - DLG_BUTTON_WIDTH,
				    TAB_HEIGHT + 3 * DLG_BORDER +
				    DLG_BUTTON_HEIGHT, DLG_BUTTON_WIDTH,
				    DLG_BUTTON_HEIGHT, _("&Browse"));
    m_pBrowseButton->callback(OnBrowseButton);
    m_pConfirmDelete = new Fl_Check_Button(2 * DLG_BORDER + PROMPT_WIDTH,
					   TAB_HEIGHT + 4 * DLG_BORDER +
					   2 * DLG_BUTTON_HEIGHT,
					   w() - 4 * DLG_BORDER,
					   DLG_INPUT_HEIGHT,
					   _("Confirm before Delete:"));
    m_pConfirmDelete->align(FL_ALIGN_LEFT);
    m_pConfirmDelete->value(Options::GetConfirmDelete() == true ? 1 : 0);
    pGroup->end();

    // Create the second page for the tab
    pGroup = new Fl_Group(2 * DLG_BORDER,
			  DLG_BORDER + TAB_HEIGHT,
			  w() - 4 * DLG_BORDER,
			  h() - 5 * DLG_BORDER - DLG_BUTTON_HEIGHT,
			  _("Date Book"));
    m_pDayBegins = new Fl_Choice(2 * DLG_BORDER + PROMPT_WIDTH,
				 TAB_HEIGHT + 2 * DLG_BORDER,
				 CHOICE_WIDTH,
				 DLG_BUTTON_HEIGHT, _("Workday Begins:"));
    PixilDT::GetAMPM(strAM, strPM);
    for (i = 0; i < 23; ++i) {
	if (strAM.length() != 0) {
	    // Twelve hour clock
	    j = ((i + 1) % 12);
	    if (j == 0) {
		j = 12;
	    }
	    pszHour[i] =
		new char[3 + max(strAM.length(), strPM.length()) + 1];
	    sprintf(pszHour[i], "%d %s", j,
		    (i + 1) / 12 == 0 ? strAM.c_str() : strPM.c_str());
	} else {
	    // 24 hour clock
	    pszHour[i] = new char[3];
	    sprintf(pszHour[i], "%d", i + 1);
	}
    }
    m_pMenuDayBegins = CreateChoice(23, pszHour, false);
    m_pDayBegins->menu(m_pMenuDayBegins);
    m_pDayBegins->value(Options::GetDayBegins() ==
			0 ? 8 - 1 : Options::GetDayBegins() - 1);
    for (i = 0; i < 23; ++i) {
	delete pszHour[i];
    }
    m_pWeekBegins = new Fl_Choice(2 * DLG_BORDER + PROMPT_WIDTH,
				  TAB_HEIGHT + 3 * DLG_BORDER +
				  DLG_BUTTON_HEIGHT, CHOICE_WIDTH,
				  DLG_BUTTON_HEIGHT, _("Week Begins:"));
    m_pMenuWeekBegins = CreateChoice(2, pszDay, true);
    m_pWeekBegins->menu(m_pMenuWeekBegins);
    m_pWeekBegins->value(Options::GetWeekBegins());
    pGroup->end();		// End the second page

    // End the tab widget
    pTabs->end();

    // Create the buttons
    m_pOKButton =
	new Fl_Return_Button(w() - 3 * DLG_BORDER - 3 * DLG_BUTTON_WIDTH,
			     h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
			     DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, fl_ok);
    m_pCancelButton =
	new Fl_Button(w() - 2 * DLG_BORDER - 2 * DLG_BUTTON_WIDTH,
		      h() - DLG_BUTTON_HEIGHT - DLG_BORDER, DLG_BUTTON_WIDTH,
		      DLG_BUTTON_HEIGHT, fl_cancel);
    m_pCancelButton->shortcut("^[");
    m_pHelpButton = new Fl_Button(w() - DLG_BORDER - DLG_BUTTON_WIDTH,
				  h() - DLG_BUTTON_HEIGHT - DLG_BORDER,
				  DLG_BUTTON_WIDTH,
				  DLG_BUTTON_HEIGHT, _("&Help"));
    m_pHelpButton->callback(OnHelpButton);

    // Finish the dialog
    end();

    // The DoModal method will show this dialog
}


//--------------------------------------------------------------//
// Destructor.                                                  //
//--------------------------------------------------------------//
OptionsDlg::~OptionsDlg()
{
    FreeTranslatedMenu(m_pMenuApp);
    FreeTranslatedMenu(m_pMenuDayBegins);
    FreeTranslatedMenu(m_pMenuWeekBegins);
}


//--------------------------------------------------------------//
// Run the modal dialog.                                        //
//--------------------------------------------------------------//
int
OptionsDlg::DoModal()
{
    int nReturn =::DoModal(this, m_pOKButton, m_pCancelButton);

    if (nReturn == 1) {
	// Get the values from this dialog
	Options::SetMainPage(m_pAppChoice->value());
	Options::SetConfirmDelete(m_pConfirmDelete->value() == 1);
	Options::SetDayBegins(m_pDayBegins->value() + 1);
	if (Options::GetWeekBegins() != m_pWeekBegins->value()) {
	    // Change the setting
	    Options::SetWeekBegins(m_pWeekBegins->value());

	    // Refresh displays
	    PixilDT::GetApp()->GetMainWindow()->Notify(BEGIN_WEEK_CHANGED, 0);
	}
	if (Options::GetDatabasePath() != m_pDataDir->value()) {
	    // Change the database path
	    Options::SetDatabasePath(m_pDataDir->value());

	    // Close all open databases
	    NxDbAccess::CloseAll();

	    // Refresh all data
	    PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED,
						       0);
	    PixilDT::GetApp()->GetMainWindow()->Notify(NOTES_CHANGED, 0);
	    PixilDT::GetApp()->GetMainWindow()->Notify(SCHEDULER_CHANGED, 0);
	    PixilDT::GetApp()->GetMainWindow()->Notify(TODO_LIST_CHANGED, 0);
	}
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Browse button was clicked (static callback).                 //
//--------------------------------------------------------------//
void
OptionsDlg::OnBrowseButton(Fl_Widget * pWidget, void *pUserData)
{
    InputBox *pInputBox;
    OptionsDlg *pThis =
	(OptionsDlg *) (pWidget->parent()->parent()->parent());

    // Get the directory name
    pInputBox = new InputBox(_("Data Directory"),
			     PixilDT::GetApp()->GetMainWindow(),
			     pThis->m_pDataDir->value(),
			     256,
			     HELP_OPTIONS_DLG,
			     Validate,
			     pThis,
			     NULL, _("Please enter the data directory:"));
    if (pInputBox->GetEntry().length() > 0) {
	pThis->m_pDataDir->value(pInputBox->GetEntry().c_str());
    }
    delete pInputBox;
}


//--------------------------------------------------------------//
// Help button was clicked (static callback).                   //
//--------------------------------------------------------------//
void
OptionsDlg::OnHelpButton(Fl_Widget * pWidget, void *pUserData)
{
    PixilDT::GetApp()->ShowHelp(HELP_OPTIONS_DLG);
}


//--------------------------------------------------------------//
// Validate a new data directory (static callback).             //
//--------------------------------------------------------------//
bool
OptionsDlg::Validate(const char *pszString,
		     Fl_Widget * pThis, void *pUserData)
{
    bool bNotBlank = false;
    int i;

    // The directory cannot start or end with a blank
    if (!isspace(pszString[0]) && !isspace(pszString[strlen(pszString) - 1])) {
	// The directory cannot be completely blank
	for (i = 0; pszString[i] != '\0'; ++i) {
	    if (!isspace(pszString[i])) {
		bNotBlank = true;
		break;
	    }
	}
    }
    return (bNotBlank);
}

--- NEW FILE: Images.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class used to access all images in the application.          //
//--------------------------------------------------------------//
#ifndef IMAGES_H_

#define IMAGES_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <cassert>
#include <FL/fl_draw.H>
#include <FL/Fl_Pixmap.H>
#ifndef WIN32
#include <FL/x.H>		// For Pixmap
#endif /*  */
class Images
{
  public:enum ImageID
    { ADDRESSBOOK_IMAGE = 0, BIGLEFT_ICON, BIGRIGHT_ICON, BOX_ICON, CALENDAR_ICON, CHECKBOX_ICON, CURHELP_ICON, DISABLED_CALENDAR_ICON, DISABLED_COPY_ICON, DISABLED_CUT_ICON, DISABLED_NOTES, DISABLED_PASTE_ICON, DISABLED_PRINT_ICON, DISABLED_SAVE_ICON, DISABLED_UNDO_ICON, EDITCOPY_ICON, EDITCUT_ICON, EDITPASTE_ICON, EDITUNDO_ICON, FILEPRINT_ICON, FILESAVE_ICON, FIND_ICON, LEFT_ICON, NEWITEM_ICON, NOTES_IMAGE, NOTES_ICON, PIXIL_ICON, PRIVATE_ICON, REPEAT_ICON, RIGHT_ICON, SCHEDULER_IMAGE, SMALL_DOWN_ICON, SMALL_UP_ICON, TIME_ICON, TODOLIST_IMAGE, MAX_IMAGES,	// Not an image, used for range checking
    };
      Images();			// Default constructor
     ~Images();			// Destructor
    static void Destroy();	// Destroy all image storage
    inline static Fl_Pixmap *GetAddressBookImage()	// Get the Address Book button image
    {
	return (m_pThis->GetImage(ADDRESSBOOK_IMAGE));
    }
    inline static Fl_Pixmap *GetBigLeftIcon()	// Get the big left arrow icon
    {
	return (m_pThis->GetImage(BIGLEFT_ICON));
    }
    inline static Fl_Pixmap *GetBigRightIcon()	// Get the big right arrow icon
    {
	return (m_pThis->GetImage(BIGRIGHT_ICON));
    }
    inline static Fl_Pixmap *GetBoxIcon()	// Get the unchecked box icon
    {
	return (m_pThis->GetImage(BOX_ICON));
    }
    inline static Fl_Pixmap *GetCalendarIcon()	// Get the date/calendar icon
    {
	return (m_pThis->GetImage(CALENDAR_ICON));
    }
    inline static Fl_Pixmap *GetCheckboxIcon()	// Get the checked box icon
    {
	return (m_pThis->GetImage(CHECKBOX_ICON));
    }
    static Fl_Pixmap *GetDisabledImage(int nImage);	// Get the image with possible color changes
    static Fl_Pixmap *GetImage(int nImage);	// Get an image
    inline static Fl_Pixmap *GetLeftIcon()	// Get the Left arrow icon
    {
	return (m_pThis->GetImage(LEFT_ICON));
    }
    inline static Fl_Pixmap *GetNotesImage()	// Get the Notes button image
    {
	return (m_pThis->GetImage(NOTES_IMAGE));
    }
    inline static Fl_Pixmap *GetNotesIcon()	// Get the small "notes available" icon
    {
	return (m_pThis->GetImage(NOTES_ICON));
    }
    inline static Fl_Pixmap *GetPixilIcon()	// Get the Pixil window icon
    {
	return (m_pThis->GetImage(PIXIL_ICON));
    }

#ifndef WIN32
    static unsigned long GetPixmap(int nIndex);	// Get an X Pixmap for an image
#endif /*  */
    inline static Fl_Pixmap *GetPrivateIcon()	// Get the small "private entry" icon
    {
	return (m_pThis->GetImage(PRIVATE_ICON));
    }
    inline static Fl_Pixmap *GetRepeatIcon()	// Get the Repeat arrow icon
    {
	return (m_pThis->GetImage(REPEAT_ICON));
    }
    inline static Fl_Pixmap *GetRightIcon()	// Get the Right arrow icon
    {
	return (m_pThis->GetImage(RIGHT_ICON));
    }
    inline static Fl_Pixmap *GetSchedulerImage()	// Get the Scheduler button image
    {
	return (m_pThis->GetImage(SCHEDULER_IMAGE));
    }
    inline static Fl_Pixmap *GetSmallDownIcon()	// Get the Small Down arrow icon
    {
	return (m_pThis->GetImage(SMALL_DOWN_ICON));
    }
    inline static Fl_Pixmap *GetSmallUpIcon()	// Get the Small Up arrow icon
    {
	return (m_pThis->GetImage(SMALL_UP_ICON));
    }
    inline static Fl_Pixmap *GetTimeIcon()	// Get the Time icon
    {
	return (m_pThis->GetImage(TIME_ICON));
    }
    inline static Fl_Pixmap *GetToDoListImage()	// Get ToDo List button image
    {
	return (m_pThis->GetImage(TODOLIST_IMAGE));
    }
  private:static char **m_ppszDisabledXPM[];
    // Disabled XPM's with different colors from the original XPM
    static char const *const *m_ppszXPM[];	// Source XPM's
    static Images *m_pThis;	// Singleton pointer
};


#endif /*  */

--- NEW FILE: NxDb0002.txt ---
add
#1 0,0,0,"Baggins","Frodo ","Middle Earth, Inc.","CEO",0,1,2,3,4,5,6,"555.555.0001","555.555.0002 x123","555.555-0003","555.555.0004","555.555.0005","frodo at middleearth.net","http://onering.net","Bagend #1","Hobbitten","Shire","00001","Middele Earth","04/04/1940","06/06/1960","Custom Value","Custom Value","Custom Value","Custom Value",""

--- NEW FILE: NxDb0001.txt ---
add_category
#1 0,"Unfiled"
#2 1,"Business"
#3 2,"Personal"

--- NEW FILE: SplashDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Splash Screen (dialog).                                      //
//--------------------------------------------------------------//
#ifndef SPLASHSCREEN_H_

#define SPLASHSCREEN_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <FL/Fl_Pixmap.H>
#include <FL/Fl_Window.H>
class SplashDlg:public Fl_Window
{
  public:SplashDlg(double fSeconds,
	      // Constructor
	      bool & bTimedOut);
     ~SplashDlg();		// Destructor
  private:  bool * m_pbTimedOut;
    // Time out flag for caller
    Fl_Pixmap *m_pPixmap;	// The splash image
    static SplashDlg *m_pThis;	// Singleton pointer
    static void Timeout(void *pUserData);	// Timeout handler
};


#endif /*  */

--- NEW FILE: SchedulerWeekly.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler Weekly tab page                                    //
//--------------------------------------------------------------//
#ifndef SCHEDULERWEEKLY_H_

#define SCHEDULERWEEKLY_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Pixmap.H>
#include "Messages.h"
#include "ScheduleContainer.h"
using namespace std;
class SchedulerWeekly:public Fl_Group
{
  public:SchedulerWeekly(int nX,
		    // Constructor
		    int nY, int nWidth, int nHeight);
     ~SchedulerWeekly();	// Destructor
    int Message(PixilDTMessage nMessage,	// Message from the parent widget
		int nInfo);
    void Print();		// Print this data
  private:  Fl_Box * m_pDate;	// Date banner at the top of the page
    Fl_Box *m_pDow[7];		// Day of week titles
    Fl_Button *m_pGoToButton;	// Goto button
    Fl_Button *m_pLeftButton;	// Left arrow button
    Fl_Button *m_pRightButton;	// Right arrow button
    Fl_Button *m_pTodayButton;	// Today button
    Fl_Pixmap *m_pLeftPixmap;	// Left arrow pixmap
    Fl_Pixmap *m_pRightPixmap;	// Right arrow pixmap
    ScheduleContainer *m_pScheduleContainer;	// The container for the daily schedules
    string m_strBoxLabel[7];	// Day-of-week labels
    string m_strDateLabel;	// Label for the banner at the top of the page
    time_t m_nDate;		// Currently displayed Sunday
    void DisplayDay(time_t nDate);	// Display a particular day
    static void OnGotoButton(Fl_Widget * pWidget,	// Process a click on the goto buttton
			     void *pUserData);
    static void OnLeftButton(Fl_Widget * pWidget,	// Process a click on the left buttton
			     void *pUserData);
    static void OnRightButton(Fl_Widget * pWidget,	// Process a click on the right buttton
			      void *pUserData);
    static void OnTodayButton(Fl_Widget * pWidget,	// Process a click on the today buttton
			      void *pUserData);
  public:void Refresh()
    {
	m_pScheduleContainer->Refresh(m_nDate);
    }
};


#endif /*  */

--- NEW FILE: InfoDBDef.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// "Info" database definition fields.                           //
//--------------------------------------------------------------//
#ifndef INFODBDEF_H_

#define INFODBDEF_H_

#define INFO_TYPE 10

// Info
field iFields[] = {
    {
     'i', 1, 0}
    ,				// Field 0:infoid
    {
     'c', INFO_TYPE, 0}
    ,				//       1:info_type
    {
     0}
};


// Database
fildes iFile = {
    0, 0, 0, "dbf", 2, &iFields[0]
};


#endif /*  */

--- NEW FILE: CustomFieldEditor.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Custom Field Editor dialog.                                  //
//--------------------------------------------------------------//
#ifndef CUSTOMFIElDEDITOR_H_

#define CUSTOMFIELDEDITOR_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Window.H>
#include "CustomFieldDB.h"
#include "PixilMainWnd.h"
class CustomFieldEditor:public Fl_Window
{
  public:CustomFieldEditor(PixilMainWnd * pParent);
    // Constructor
    ~CustomFieldEditor();	// Destructor
  private:char m_szLabel[4][32];
    // Labels for the input fields
    Fl_Button *m_pCancelButton;	// The Cancel button
    Fl_Button *m_pHelpButton;	// The Help button
    Fl_Button *m_pOKButton;	// The OK button
    Fl_Input *m_pInput[4];	// Input fields for each of the 4 custom fields
    CustomFieldDB *m_pDB;	// Pointer to the database to be used for this dialog
    PixilMainWnd *m_pParent;	// The parent window
    static void OnHelpButton(Fl_Widget * pWidget,	// Help Button press
			     void *pUserData);
    static void OnOKButton(Fl_Widget * pWidget,	// OK Button press
			   void *pUserData);
};


#endif /*  */

--- NEW FILE: TimeFunc.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Date/Time utilities.  These functions process dates and      //
// times.  Many of the calculation routines will determine the  //
// number of days, weeks, months or years between two dates     //
// taking daylight savings time into consideration.  Otherwise  //
// the possible one hour difference in the duration of a day    //
// might produce incorrect results.                             //
//--------------------------------------------------------------//
#ifndef TIMEFUNC_H_

#define TIMEFUNC_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
using namespace std;
time_t AddDays(time_t nDate,	// Add some number of days and return the new date at midnight
	       int nDays);
int DaysBetween(time_t nDate1,	// Get the number of days between two dates
		time_t nDate2);
string FormatDate(time_t nDate);	// Format the date portion of a date/time
string FormatDayOfWeek(time_t nDate);	// Get the day-of-week for a date/time
string FormatMonth(time_t nDate);	// Format the month as "longname, year"
string FormatShortTime(time_t nDate);	// Format the time portion of a date/time as HH[:MM](AM/PM)
string FormatTime(time_t nDate);	// Format the time portion of a date/time as HH:MM (AM/PM)
const char *GetDateError(int nError);	// Get the text for a date error from ValidateDate
string GetDayOfWeek(int nDay);	// Get the day of week for a date
string GetDayOfWeek(time_t nDate);	// Get the day of week for a date
string GetDayOfWeekAbbr(int nDay);	// Get the day of week abbreviation for a date
string GetDayOfWeekAbbr(time_t nDate);	// Get the day of week abbreviation for a date
int GetDow(time_t nDate);	// Get the day of week for a date
string GetMonthAbbr(int nMonth);	// Get the abbreviated name of a month
string GetMonthAbbr(time_t nDate);	// Get the abbreviated name of a month
string GetMonthName(int nMonth);	// Get the name of a month
string GetMonthName(time_t nDate);	// Get the name of a month
int GetMonthWeek(time_t nDate);	// Get the week of the month
const char *GetTimeError(int nError);	// Get the text for a time error from ValidateTime
bool IsDayOfMonth(time_t nDate,	// Is this day on a particular day of month (the one used by the second date)
		  time_t nDom);
bool IsDayOfYear(time_t nDate,	// Is this day on the same month and day (as the second date)
		 time_t nDoy);
time_t MakeDate(int nYear,	// Make a date for midnight of the given day
		int nMonth, int nDay);
int MonthsBetween(time_t nDate1,	// Get the number of months between two dates
		  time_t nDate2);
time_t NormalizeDate(time_t nDate);	// Normalize a date to midnight
bool TestNumeric(const string & strData);	// Test a string for all numeric characters
int ValidateDate(const char *pszDate,	// Validate a date entry string
		 time_t & nDate);
int ValidateTime(const char *pszTime,	// Validate a time entry string
		 int &nTime);
int WeeksBetween(time_t nDate1,	// Determine the number of weeks between two dates
		 time_t nDate2);
int YearsBetween(time_t nDate1,	// Get the number of years between the January 1st's prior to the two dates
		 time_t nDate2);

//--------------------------------------------------------------//
// Inline functions.                                            //
//--------------------------------------------------------------//
inline int
DaysBetween(time_t nDate1,	// Get the number of days between two dates accounting for daylight savings time
	    time_t nDate2)
{

#ifdef DEBUG
    assert(nDate1 == NormalizeDate(nDate1));	// Must be "normalized" dates (midnight)
    assert(nDate2 == NormalizeDate(nDate2));	// Must be "normalized" dates (midnight)
#endif /*  */
    return ((nDate1 - nDate2 +
	     (12 * 60 * 60 - 1) * (nDate1 >=
				   nDate2 ? 1 : -1)) / (24 * 60 * 60));
}
inline int
GetDow(int nYear,		// Get the day of week for a date
       int nMonth, int nDay)
{
    return (GetDow(MakeDate(nYear, nMonth, nDay)));
}
inline int
GetMonthWeek(int nDay)		// Get the week of the month, (first Tuesday will always be week 0)
{
    return (nDay / 7);
}

inline time_t
SubtractDays(time_t nDate,	// Subtract some number of days from a date and return a new date at midnight
	     int nDays)
{
    return (AddDays(nDate, -nDays));
}
inline int
WeeksBetween(int nYear1,	// Get the number of weeks between the Sunday's prior to the two dates
	     int nMonth1, int nDay1, time_t nDate2)
{
    return (WeeksBetween(MakeDate(nYear1, nMonth1, nDay1), nDate2));
}


//--------------------------------------------------------------//
// Second level of inline functions.                            //
//--------------------------------------------------------------//
inline int
DaysBetween(int nYear1,		// Get the number of days between two dates
	    int nMonth1, int nDay1, time_t nDate2)
{
    return (DaysBetween(MakeDate(nYear1, nMonth1, nDay1), nDate2));
}


#endif /*  */

--- NEW FILE: Printer.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
[...2808 lines suppressed...]
			  nHeight, vLine[0].c_str(), FL_ALIGN_LEFT);

	    // Output remaining lines of text
	    for (nLine = 1; nLine < vLine.size(); ++nLine) {
		Win32DrawText(nX,
			      nY - nLine * nHeaderHeight,
			      nWidth,
			      nHeight, vLine[nLine].c_str(), FL_ALIGN_LEFT);
	    }
	}
    } else {
	nHeightUsed = 0;
    }

    // Reset the DC
    ::SelectObject(m_hDC, hOriginalFont);

    return (true);		// No error reporting yet...
}
#endif

--- NEW FILE: SchedulerYearly.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler Yearly tab page                                    //
//--------------------------------------------------------------//
#include "config.h"
#include <cassert>
#include <climits>
#include <cstdio>
#include <FL/Fl.H>
#include <FL/fl_ask.H>
#include "Dialog.h"
#include "HelpID.h"
#include "Images.h"
#include "InputBox.h"
#include "Options.h"
#include "PixilDT.h"
#include "SchedulerDB.h"
#include "SchedulerYearly.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


using namespace std;


#define BUTTON_BORDER 2
#define DATE_BORDER   4


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
SchedulerYearly::SchedulerYearly(int nX, int nY, int nWidth, int nHeight)
    :
Fl_Group(nX, nY, nWidth, nHeight, _("Yearly"))
{
    Fl_Group *pGroup;
    int i;
    int j;
    int nBoxHeight;
    int nBoxWidth;
    int nGroupHeight;
    int nGroupWidth;
    int nGroupX;
    int nGroupY;

    // Create the top line of the page, in a group for resizing
    pGroup = new Fl_Group(x() + DLG_BORDER,
			  y() + DLG_BORDER,
			  w() - 2 * DLG_BORDER, DLG_INPUT_HEIGHT);
    nGroupX = pGroup->x();
    nGroupY = pGroup->y();
    nGroupWidth = pGroup->w();
    m_pLeftButton = new Fl_Button(nGroupX,
				  nGroupY,
				  IMAGE_BUTTON_WIDTH, DLG_INPUT_HEIGHT);
    m_pLeftPixmap = Images::GetBigLeftIcon();
    m_pLeftPixmap->label(m_pLeftButton);
    m_pLeftButton->callback(OnLeftButton);
    m_pGoToButton =
	new Fl_Button(nGroupX + IMAGE_BUTTON_WIDTH + BUTTON_BORDER, nGroupY,
		      DLG_BUTTON_WIDTH, DLG_INPUT_HEIGHT, _("&Go To"));
    m_pGoToButton->callback(OnGotoButton);
    m_pRightButton =
	new Fl_Button(nGroupX + IMAGE_BUTTON_WIDTH + 2 * BUTTON_BORDER +
		      DLG_BUTTON_WIDTH, nGroupY, IMAGE_BUTTON_WIDTH,
		      DLG_INPUT_HEIGHT);
    m_pRightPixmap = Images::GetBigRightIcon();
    m_pRightPixmap->label(m_pRightButton);
    m_pRightButton->callback(OnRightButton);
    m_pDate =
	new Fl_Box(nGroupX + DLG_BORDER + 2 * IMAGE_BUTTON_WIDTH +
		   2 * BUTTON_BORDER + DLG_BUTTON_WIDTH, nGroupY,
		   nGroupWidth - 2 * DLG_BORDER - 2 * IMAGE_BUTTON_WIDTH -
		   2 * BUTTON_BORDER - 2 * DLG_BUTTON_WIDTH,
		   DLG_INPUT_HEIGHT);
    m_pDate->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
    m_pDate->box(FL_DOWN_BOX);
    m_pDate->color(FL_WHITE);
    m_pTodayButton = new Fl_Button(nGroupX + nGroupWidth - DLG_BUTTON_WIDTH,
				   nGroupY,
				   DLG_BUTTON_WIDTH,
				   DLG_INPUT_HEIGHT, _("&Today"));
    m_pTodayButton->callback(OnTodayButton);
    pGroup->end();
    pGroup->resizable(m_pDate);

    // Create the yearly view
    pGroup = new Fl_Group(x() + DLG_BORDER,
			  y() + 2 * DLG_BORDER + DLG_INPUT_HEIGHT,
			  w() - 2 * DLG_BORDER,
			  h() - 3 * DLG_BORDER - DLG_INPUT_HEIGHT);
    pGroup->box(FL_DOWN_BOX);
    resizable(pGroup);
    nGroupX = pGroup->x();
    nGroupY = pGroup->y();
    nGroupWidth = pGroup->w();
    nGroupHeight = pGroup->h();
    nBoxWidth = (nGroupWidth - Fl::box_dw(FL_DOWN_BOX)) / 3;
    nBoxHeight = (nGroupHeight - Fl::box_dh(FL_DOWN_BOX)) / 4;
    for (i = 0; i < 4; ++i) {
	for (j = 0; j < 3; ++j) {
	    m_pMonth[i * 3 + j] =
		new Fl_Group(nGroupX + (Fl::box_dw(FL_DOWN_BOX) >> 1) +
			     j * nBoxWidth,
			     nGroupY + (Fl::box_dh(FL_DOWN_BOX) >> 1) +
			     i * nBoxHeight,
			     (j ==
			      2 ? nGroupWidth - Fl::box_dw(FL_DOWN_BOX) -
			      2 * nBoxWidth : nBoxWidth),
			     (i ==
			      3 ? nGroupHeight - Fl::box_dh(FL_DOWN_BOX) -
			      3 * nBoxHeight : nBoxHeight));
	    m_pMonth[i * 3 + j]->box(FL_BORDER_BOX);
	    m_pMonth[i * 3 + j]->color(FL_WHITE);
	    CreateMonth(i * 3 + j);
	    m_pMonth[i * 3 + j]->end();
	}
    }

    // Finish with this group
    pGroup->end();
    pGroup->resizable(pGroup);

    // Finish with this widget
    end();

    // Go display today's date
    DisplayDay(time(NULL));
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
SchedulerYearly::~SchedulerYearly()
{
    delete m_pLeftPixmap;
    delete m_pRightPixmap;
}


//--------------------------------------------------------------//
// Create the Fl_Boxes for a month.                             //
// Each monthly box is divided into 7 vertical pieces and 7     //
// horizontal pieces.  The top vertical piece is twice the      //
// height of any others and is not divided horizontally.  This  //
// is where the month name goes.  The others are where the day  //
// numbers go.  See the UpdateMonth method for how the days are //
// actually displayed.
//--------------------------------------------------------------//
void
SchedulerYearly::CreateMonth(int nIndex)
{
    Fl_Box *pBox;
    int i;
    int j;
    int nH = m_pMonth[nIndex]->h();
    int nHeight = nH / 8;
    int nW = m_pMonth[nIndex]->w();
    int nWidth = (nW - 2 * Fl::box_dw(FL_DOWN_BOX)) / 7;
    int nX = m_pMonth[nIndex]->x();
    int nY = m_pMonth[nIndex]->y();

    // Create the box for the month name
    pBox = new Fl_Box(nX + (Fl::box_dw(FL_DOWN_BOX) >> 1),
		      nY, nW - Fl::box_dw(FL_DOWN_BOX), nH - 6 * nHeight);
    m_strMonthLabel[nIndex] =::GetMonthName(nIndex);
    pBox->
	align(FL_ALIGN_TOP | FL_ALIGN_CENTER | FL_ALIGN_INSIDE |
	      FL_ALIGN_CLIP);
    pBox->box(FL_FLAT_BOX);
    pBox->color(FL_WHITE);
    pBox->label(m_strMonthLabel[nIndex].c_str());

    // Now create each box for the dates
    for (i = 0; i < 6; ++i) {
	for (j = 0; j < 7; ++j) {
	    pBox =
		new Fl_Box(nX + (Fl::box_dw(FL_DOWN_BOX) >> 1) + j * nWidth +
			   DATE_BORDER, nY + nH - (7 - i) * nHeight,
			   (j ==
			    6 ? nW - 6 * nWidth -
			    2 * Fl::box_dw(FL_DOWN_BOX) : nWidth) -
			   DATE_BORDER, nHeight);
	    pBox->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
	    pBox->box(FL_FLAT_BOX);
	    pBox->labelfont(FL_HELVETICA_BOLD);
	    pBox->labelsize((4 * labelsize()) / 5);
	}
    }
}


//--------------------------------------------------------------//
// Display the year for a particular day.                       //
//--------------------------------------------------------------//
void
SchedulerYearly::DisplayDay(time_t nDate)
{
    char szString[16];
    int i;
    time_t nToday = time(NULL);
    struct tm *pTm;

    // Get the start of the year
    pTm = localtime(&nDate);
    pTm->tm_isdst = -1;
    pTm->tm_sec = 0;
    pTm->tm_min = 0;
    pTm->tm_hour = 0;
    pTm->tm_mday = 1;
    pTm->tm_mon = 0;
    m_nDate = mktime(pTm);

    // Fix the banner title's label
    sprintf(szString, "%d", pTm->tm_year + 1900);
    m_strDateLabel = szString;
    m_pDate->label(m_strDateLabel.c_str());

    // Get a boolean flag for events for each day of the year
    SchedulerDB::GetSchedulerDB()->GetYearlyEvents(m_bEvent, m_nDate);

    // Refresh each month's group
    for (i = 0; i < 12; ++i) {
	UpdateMonth(i);
    }

    // Enable or disable the Today button based on what day is being shown
    pTm = localtime(&nToday);
    pTm->tm_isdst = -1;
    pTm->tm_sec = 0;
    pTm->tm_min = 0;
    pTm->tm_hour = 0;
    pTm->tm_mday = 1;
    pTm->tm_mon = 0;
    nToday = mktime(pTm);
    if (nToday == m_nDate) {
	m_pTodayButton->deactivate();
    } else {
	m_pTodayButton->activate();
    }

    // Redraw the entire widget
    redraw();
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
SchedulerYearly::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case BEGIN_WEEK_CHANGED:	// Beginning day of week has changed
    case SCHEDULER_CHANGED:	// Scheduler data changed, go refresh the display
	DisplayDay(m_nDate);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Process a click on the goto button.                          //
//--------------------------------------------------------------//
void
SchedulerYearly::OnGotoButton(Fl_Widget * pWidget, void *pUserData)
{
    char szYear[5];
    InputBox *pDlg;
    int nYear;
    SchedulerYearly *pThis =
	reinterpret_cast < SchedulerYearly * >(pWidget->parent()->parent());
    struct tm *pTm = localtime(&(pThis->m_nDate));

    sprintf(szYear, "%04d", pTm->tm_year + 1900);
    pDlg = new InputBox(_("Select Year"), PixilDT::GetApp()->GetMainWindow(), szYear, 4,	// Maximum size
			HELP_NO_TOPIC,	// Help ID - no topic
			ValidateYear,	// Validation function
			NULL,	// Widget for validation
			NULL,	// Extra validation info
			_("Please enter the year to be viewed:"));

    // Was a new year entered
    if (pDlg->GetEntry().length() > 0) {
	nYear = atoi(pDlg->GetEntry().c_str()) - 1900;
	pThis->DisplayDay(::MakeDate(nYear, 1, 1));
    }
    // Clean up
    delete pDlg;
}


//--------------------------------------------------------------//
// Process a click on the left button.                          //
//--------------------------------------------------------------//
void
SchedulerYearly::OnLeftButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerYearly *pThis =
	reinterpret_cast < SchedulerYearly * >(pWidget->parent()->parent());
    struct tm *pTm;

    // Only go left if not at beginning of the possible time range
    if (pThis->m_nDate > 366 * 24 * 60 * 60) {
	pTm = localtime(&pThis->m_nDate);
	pTm->tm_isdst = -1;
	--pTm->tm_year;
	pThis->DisplayDay(mktime(pTm));
    }
}


//--------------------------------------------------------------//
// Process a click on the right button.                         //
//--------------------------------------------------------------//
void
SchedulerYearly::OnRightButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerYearly *pThis =
	reinterpret_cast < SchedulerYearly * >(pWidget->parent()->parent());
    struct tm *pTm;

    // Only go right if not at end of the possible time range
    if (pThis->m_nDate <= LONG_MAX - (365 + 366) * 24 * 60 * 60) {
	pTm = localtime(&pThis->m_nDate);
	pTm->tm_isdst = -1;
	++pTm->tm_year;
	pThis->DisplayDay(mktime(pTm));
    }
}


//--------------------------------------------------------------//
// Process a click on the Today button.  The button is within a //
// group within this page hence the parent()->parent() to get   //
// to this object.                                              //
//--------------------------------------------------------------//
void
SchedulerYearly::OnTodayButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerYearly *pThis =
	reinterpret_cast < SchedulerYearly * >(pWidget->parent()->parent());

    // Go display the current date
    pThis->DisplayDay(time(NULL));
}


//--------------------------------------------------------------//
// Print this page - not implemented.                           //
//--------------------------------------------------------------//
void
SchedulerYearly::Print()
{
    fl_alert(_
	     ("The yearly version of the Scheduler data cannot be printed."));
}


//--------------------------------------------------------------//
// Update a month for the currently displayed date.             //
//--------------------------------------------------------------//
void
SchedulerYearly::UpdateMonth(int nIndex)
{
    static const char *pszDayNumber[32] = {
	"",
	"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
	"11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
	"21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
	"31",
    };
    const char *pszLabel;
    Fl_Box *pBox;
    int i;
    int nColor;
    int nLabelColor;
    static const int nMDaysLeap[12] =
	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    static const int nMDaysNonLeap[12] =
	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int nMonth;
    int nStartDay;
    int nToday;
    int nWDay;
    int nYear;
    const int *pnDaysPerMonth;
    time_t nDate;
    struct tm *pTm;

    // The month name does not change

    // Get the day of month for today
    nDate = time(NULL);
    pTm = localtime(&nDate);
    nToday = pTm->tm_mday;
    nMonth = pTm->tm_mon;
    nYear = pTm->tm_year;

    // Get the day of week of the start of this month
    pTm = localtime(&m_nDate);
    pTm->tm_isdst = -1;
    pTm->tm_mon = nIndex;
    nDate = mktime(pTm);
    pTm = localtime(&nDate);
    nWDay = pTm->tm_wday - Options::GetWeekBegins();
    if (nWDay < 0) {
	nWDay += 7;
    }
    nStartDay = -nWDay + 1;
    pnDaysPerMonth = ((pTm->tm_year % 4) == 0 ? nMDaysLeap : nMDaysNonLeap);

    // Reset the day of month for today if not this month
    if (nMonth != pTm->tm_mon || nYear != pTm->tm_year) {
	nToday = 100;		// Just put it out-of-range
    }
    // Set the labels and colors for each button
    for (i = 0; i < 42; ++i, ++nStartDay) {
	if (nStartDay <= 0 || nStartDay > pnDaysPerMonth[pTm->tm_mon]) {
	    pszLabel = pszDayNumber[0];
	    nLabelColor = FL_BLACK;
	    nColor = FL_WHITE;
	} else {
	    pszLabel = pszDayNumber[nStartDay];
	    nLabelColor = (nStartDay == nToday ? FL_RED : FL_BLACK);
	    nColor =
		(m_bEvent[pTm->tm_yday - 1 + nStartDay] ==
		 true ? FL_YELLOW : FL_WHITE);
	}

	// Depends on the order of creation of the widgets
	pBox = dynamic_cast < Fl_Box * >(m_pMonth[nIndex]->child(i + 1));
	pBox->label(pszLabel);
	pBox->labelcolor(nLabelColor);
	pBox->color(nColor);
    }
}


//--------------------------------------------------------------//
// Validate an entered year for the "goto" button.              //
//--------------------------------------------------------------//
bool
SchedulerYearly::ValidateYear(const char *pszString,
			      Fl_Widget * pWidget, void *pUserData)
{
    bool bReturn;
    int nYear;
    string strData = pszString;

    if ((bReturn = TestNumeric(pszString)) == true) {
	nYear = atoi(pszString);
	if (nYear < 1970 || nYear > 2036) {
	    bReturn = false;
	}
    }
    return (bReturn);
}

--- NEW FILE: TimeFunc.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Date/Time utilities.                                         //
//--------------------------------------------------------------//
#include "config.h"
#include <cassert>
#include <cstdio>
#include <ctime>
#include "PixilDT.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


#ifdef WIN32
#define strcasecmp stricmp	// Microsoft names it differently
#define tzset _tzset		// And again
#endif


//--------------------------------------------------------------//
// Internal functions.                                          //
//--------------------------------------------------------------//
static time_t ToDow(int nDow);	// Get a time that represents a day of the week
static time_t ToMonth(int nDow);	// Get a time that represents a month of the year


//--------------------------------------------------------------//
// Add (or subtract) some number of days to a date, return a    //
// date for midnight of the resulting day.                      //
//--------------------------------------------------------------//
time_t
AddDays(time_t nDate, int nDays)
{
    int nDiff;
    struct tm *pTm;

#ifdef DEBUG
    assert(nDate == NormalizeDate(nDate));	// Must be a "normalized" date (midnight)
#endif

    nDate += nDays * 24 * 60 * 60;
    pTm = localtime(&nDate);
    if (pTm->tm_hour > 12) {
	nDiff = 24 - pTm->tm_hour;
    } else {
	nDiff = -pTm->tm_hour;
    }
    nDate += nDiff * 60 * 60;
    return (nDate);
}


//--------------------------------------------------------------//
// Format a date.                                               //
//--------------------------------------------------------------//
string
FormatDate(time_t nDate)
{
    char szDate[16];
    string strReturn;

    if (nDate >= 24 * 60 * 60) {
	strftime(szDate, sizeof(szDate), "%x", localtime(&nDate));
	strReturn = szDate;
    }
    return (strReturn);
}


//--------------------------------------------------------------//
// Get the day of the week for a date.                          //
//--------------------------------------------------------------//
string
FormatDayOfWeek(time_t nDate)
{
    char szText[32];
    string strReturn;

    if (nDate > 24 * 60 * 60) {
	strftime(szText, sizeof(szText), "%A", localtime(&nDate));
	strReturn = szText;
    }
    return (strReturn);
}


//--------------------------------------------------------------//
// Format a Month and Year.                                     //
//--------------------------------------------------------------//
string
FormatMonth(time_t nDate)
{
    char szText[64];
    string strReturn;

    strftime(szText, sizeof(szText), "%B, %Y", localtime(&nDate));
    strReturn = szText;
    return (strReturn);
}


//--------------------------------------------------------------//
// Format a "short" time.                                       //
//--------------------------------------------------------------//
string
FormatShortTime(time_t nTime)
{
    char szTime[24];
    string strReturn;

    if (nTime >= 24 * 60 * 60) {
	struct tm *pTm = localtime(&nTime);

	if (pTm->tm_min == 0) {
	    strftime(szTime, sizeof(szTime), "%I", pTm);
	} else {
	    strftime(szTime, sizeof(szTime), "%I:%M", pTm);
	}
	strReturn = (szTime[0] == '0' ? szTime + 1 : szTime);
	strftime(szTime, sizeof(szTime), "%p", pTm);
	strReturn += szTime[0];
    }
    return (strReturn);
}


//--------------------------------------------------------------//
// Format a time.                                               //
//--------------------------------------------------------------//
string
FormatTime(time_t nTime)
{
    char szTime[24];
    string strAM;
    string strFormat;
    string strPM;
    string strReturn;

    PixilDT::GetAMPM(strAM, strPM);
    if (nTime >= 24 * 60 * 60) {
	struct tm *pTm = localtime(&nTime);

	if (strAM.length() != 0) {
	    // Twelve hour clock
	    strFormat = "%I";
	    strFormat += PixilDT::GetTimeSeparator();
	    strFormat += "%M %p";
	    strftime(szTime, sizeof(szTime), strFormat.c_str(), pTm);
	} else {
	    // 24 hour clock
	    strFormat = "%H";
	    strFormat += PixilDT::GetTimeSeparator();
	    strFormat += "%M";
	    strftime(szTime, sizeof(szTime), strFormat.c_str(), pTm);
	}
	strReturn = szTime;
    }
    return (strReturn);
}


//--------------------------------------------------------------//
// Get an error message about a date using an error message set //
// by ValidateDate.                                             //
//--------------------------------------------------------------//
const char *
GetDateError(int nError)
{
    static const char *pszError[7] = {
	N_("Year is not in the range of 1970 through 2036."),
	N_("Month is not in the range of 1 through 12."),
	N_("Day is not in the range for the entered month."),
	N_("The year contains non-numeric characters"),
	N_("The month contains non-numeric characters"),
	N_("The day-of-month contains non-numeric characters"),
	N_("The date must contain \"/\" or \"-\" delimiters between the year, month and day."),
    };
    const char *pszReturn;

    if (nError < 0 && nError >= -7) {
	pszReturn = _(pszError[-nError - 1]);
    } else {
	pszReturn = _("Unknown Date Format Error");
    }
    return (pszReturn);
}


//--------------------------------------------------------------//
// Get the day of the week for an integer day of week.          //
//--------------------------------------------------------------//
string
GetDayOfWeek(int nDay)
{
    return (GetDayOfWeek(ToDow(nDay)));
}


//--------------------------------------------------------------//
// Get the day of the week for an integer day of week.          //
//--------------------------------------------------------------//
string
GetDayOfWeek(time_t nDate)
{
    char szText[32];
    string strReturn;

    strftime(szText, sizeof(szText), "%A", localtime(&nDate));
    strReturn = szText;

    return (strReturn);
}


//--------------------------------------------------------------//
// Get the day of the week abbreviation for an integer day of   //
// week.                                                        //
//--------------------------------------------------------------//
string
GetDayOfWeekAbbr(int nDay)
{
    return (GetDayOfWeekAbbr(ToDow(nDay)));
}


//--------------------------------------------------------------//
// Get the day of the week abbreviation for an integer day of   //
// week.                                                        //
//--------------------------------------------------------------//
string
GetDayOfWeekAbbr(time_t nDate)
{
    char szText[32];
    string strReturn;

    strftime(szText, sizeof(szText), "%a", localtime(&nDate));
    strReturn = szText;

    return (strReturn);
}


//--------------------------------------------------------------//
// Get the day of the week as an integer.                       //
//--------------------------------------------------------------//
int
GetDow(time_t nDate)
{
    struct tm *pTm;

    pTm = localtime(&nDate);
    return (pTm->tm_wday);
}


//--------------------------------------------------------------//
// Get the abbreviated name of a month.                         //
//--------------------------------------------------------------//
string
GetMonthAbbr(int nMonth)
{
    return (GetMonthAbbr(ToMonth(nMonth)));
}


//--------------------------------------------------------------//
// Get the abbreviated name of a month.                         //
//--------------------------------------------------------------//
string
GetMonthAbbr(time_t nDate)
{
    char szText[32];
    string strReturn;

    strftime(szText, sizeof(szText), "%b", localtime(&nDate));
    strReturn = szText;

    return (strReturn);
}


//--------------------------------------------------------------//
// Get the name of a month.                                     //
//--------------------------------------------------------------//
string
GetMonthName(int nMonth)
{
    return (GetMonthName(ToMonth(nMonth)));
}


//--------------------------------------------------------------//
// Get the name of a month.                                     //
//--------------------------------------------------------------//
string
GetMonthName(time_t nDate)
{
    char szText[32];
    string strReturn;

    strftime(szText, sizeof(szText), "%B", localtime(&nDate));
    strReturn = szText;

    return (strReturn);
}


//--------------------------------------------------------------//
// Get week of the month for a date.  The week is calculated    //
// from the start of the month no matter which day-of-week the  //
// 1st of the month was on.  This means that, for instance, the //
// first Tuesday of the month will always be in week zero.      //
//--------------------------------------------------------------//
int
GetMonthWeek(time_t nDate)
{
    struct tm *pTm = localtime(&nDate);

    return (GetMonthWeek(pTm->tm_mday));
}


//--------------------------------------------------------------//
// Get an error message about a time using an error message set //
// by ValidateTime.                                             //
//--------------------------------------------------------------//
const char *
GetTimeError(int nError)
{
    static const char *pszError[7] = {
	N_("The time is followed by an invalid AM/PM string."),
	N_("The minutes must be zero for the last hour of a 24 hour clock."),
	N_("The minutes must be between 0 and 59."),
	N_("The hours must be between 0 and 24 for a 24 hour clock."),
	N_("The hours must be between 1 and 12."),
	N_("The hours must be numeric."),
	N_("The minutess must be numeric."),
    };
    const char *pszReturn;

    if (nError < 0 && nError >= -7) {
	pszReturn = _(pszError[-nError - 1]);
    } else {
	pszReturn = _("Unknown Time Format Error");
    }
    return (pszReturn);
}


//--------------------------------------------------------------//
// Test whether a date is on the same day of month and also     //
// provide an exception for shorter months.                     //
//--------------------------------------------------------------//
bool
IsDayOfMonth(time_t nDate, time_t nDom)
{
    bool bReturn = false;
    int nDay;
    struct tm *pTm = localtime(&nDom);

    // Get the day of month
    nDay = pTm->tm_mday;

    pTm = localtime(&nDate);
    if (pTm->tm_mday == nDay) {
	// Same day of month
	bReturn = true;
    } else if (nDay > 30 && pTm->tm_mday == 30 && (pTm->tm_mon == 3	// April
						   || pTm->tm_mon == 5	// June
						   || pTm->tm_mon == 8	// September
						   || pTm->tm_mon == 10))	// November
    {
	// Short month, call it the same day
	bReturn = true;
    } else if (nDay > 28 && pTm->tm_mon == 1)	// February
    {
	// Is this a leap year
	if ((pTm->tm_year % 4) == 0) {
	    // Leap year
	    if (nDay > 29 && pTm->tm_mday == 29) {
		// Past end of February
		bReturn = true;
	    }
	} else if (pTm->tm_mday == 28) {
	    // Past end of February
	    bReturn = true;
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Test whether a date is on the same day of year and also      //
// provide an exception for February 29th.                      //
//--------------------------------------------------------------//
bool
IsDayOfYear(time_t nDate, time_t nDoy)
{
    bool bReturn = false;
    int nDay;
    int nMonth;
    struct tm *pTm = localtime(&nDoy);

    nDay = pTm->tm_mday;
    nMonth = pTm->tm_mon;

    pTm = localtime(&nDate);
    if (pTm->tm_mon == nMonth) {
	if (pTm->tm_mday == nDay
	    || (nMonth == 1 && nDay == 29 && (pTm->tm_year % 4) != 0
		&& pTm->tm_mday == 28)) {
	    // Same day of the year
	    bReturn = true;
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Make a date from the year, month and day.                    //
//--------------------------------------------------------------//
time_t
MakeDate(int nYear, int nMonth, int nDay)
{
    time_t nDate;
    struct tm tmStruct;

    tzset();
    memset(&tmStruct, 0, sizeof(tmStruct));
    tmStruct.tm_isdst = -1;
    tmStruct.tm_mday = nDay;
    tmStruct.tm_mon = nMonth;
    tmStruct.tm_year = nYear;
    nDate = mktime(&tmStruct);
#ifdef DEBUG
    assert((int) nDate != -1);
#endif
    return (nDate);
}


//--------------------------------------------------------------//
// Return the number of months between two dates.               //
//--------------------------------------------------------------//
int
MonthsBetween(time_t nDate1, time_t nDate2)
{
    int nMonth1;
    int nYear1;
    struct tm *pTm = localtime(&nDate1);

    nMonth1 = pTm->tm_mon;
    nYear1 = pTm->tm_year;
    pTm = localtime(&nDate2);
    return (12 * (nYear1 - pTm->tm_year) + nMonth1 - pTm->tm_mon);
}


//--------------------------------------------------------------//
// Normalize a date to midnight local time.                     //
//--------------------------------------------------------------//
time_t
NormalizeDate(time_t nDate)
{
    struct tm *pTm = localtime(&nDate);

    tzset();
    pTm->tm_sec = 0;
    pTm->tm_min = 0;
    pTm->tm_hour = 0;
    return (mktime(pTm));
}


//--------------------------------------------------------------//
// Test a string for all numeric digits.                        //
//--------------------------------------------------------------//
bool
TestNumeric(const string & strData)
{
    bool bReturn = true;
    int i;
    int nMax = strData.length();

    for (i = 0; i < nMax; ++i) {
	if (!isdigit(strData[i])) {
	    bReturn = false;
	    break;
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Set up a date equivalent to a given day of week.             //
//--------------------------------------------------------------//
time_t
ToDow(int nDow)
{
    struct tm *pTm;
    time_t timeValue = time(NULL);

#ifdef DEBUG
    assert(nDow >= 0 && nDow < 7);
#endif

    pTm = localtime(&timeValue);
    pTm->tm_hour = 12;
    pTm->tm_min = 0;
    pTm->tm_sec = 0;
    timeValue = mktime(pTm);
    timeValue += (7 + nDow - pTm->tm_wday) * 24 * 60 * 60;
    return (timeValue);
}


//--------------------------------------------------------------//
// Set up a date equivalent to a given month of the year.       //
//--------------------------------------------------------------//
time_t
ToMonth(int nMonth)
{
    struct tm TM;

#ifdef DEBUG
    assert(nMonth >= 0 && nMonth < 12);
#endif

    memset(&TM, 0, sizeof(TM));
    TM.tm_year = 80;
    TM.tm_mon = nMonth;
    TM.tm_mday = 2;
    TM.tm_hour = 12;
    return (mktime(&TM));
}


//--------------------------------------------------------------//
// Validate a newly entered date.  The entered date must be a   //
// valid date in order of the locale.  The year can be a 2 or 4 //
// digit year.  If only one delimiter is found then the date is //
// assumed to be in MM/DD or DD/MM format for the current year. //
// The returned value will be 0 if the date is valid or a       //
// negative number indicating the error type if the date is not //
// valid.                                                       //
//--------------------------------------------------------------//
int
ValidateDate(const char *pszDate, time_t & nDate)
{
    char szData[16];
    int nReturn;
    string strDate = pszDate;
    unsigned int nPos1;
    unsigned int nPos2;

    // Test the date format - find the delimiters
    nPos1 = strDate.find(PixilDT::GetDateSeparator(), 0);
    if (nPos1 != string::npos) {
	nPos2 = strDate.find(PixilDT::GetDateSeparator(), nPos1 + 1);
    } else {
	nPos1 = strDate.find('/', 0);
	if (nPos1 != string::npos) {
	    nPos2 = strDate.find('/', nPos1 + 1);
	} else {
	    nPos1 = strDate.find('-', 0);
	    if (nPos1 != string::npos) {
		nPos2 = strDate.find('-', nPos1 + 1);
	    }
	}
    }

    // Was any delimiter found ?
    if (nPos1 != string::npos) {
	string strDay;
	string strMonth;
	string strYear;

	// Was only a single delimiter found ?
	if (nPos2 == string::npos) {
	    long nTime = time(NULL);
	    struct tm *pTm;

	    // Only one delimiter, the date must be MM/DD or DD/MM for the current year
	    switch (PixilDT::GetDateFormat()) {
	    case PixilDT::DATE_DMY:
	    case PixilDT::DATE_DYM:
	    case PixilDT::DATE_YDM:
		if (nPos1 > 0) {
		    strDay = strDate.substr(0, nPos1 - 1);
		}
		strMonth =
		    strDate.substr(nPos1 + 1, strDate.length() - nPos1 - 1);
		break;

		//case PixilDT::DATE_MDY:
		//case PixilDT::DATE_MYD:
		//case PixilDT::DATE_YMD:
	    default:
		if (nPos1 > 0) {
		    strMonth = strDate.substr(0, nPos1 - 1);
		}
		strDay =
		    strDate.substr(nPos1 + 1, strDate.length() - nPos1 - 1);
	    }
	    pTm = localtime(&nTime);
	    sprintf(szData, "%d", pTm->tm_year + 1900);
	    strYear = szData;
	} else {
	    // Two delimiters found, date must be in the format for the locale
	    switch (PixilDT::GetDateFormat()) {
	    case PixilDT::DATE_DMY:
		strDay = strDate.substr(0, nPos1);
		strMonth = strDate.substr(nPos1 + 1, nPos2 - nPos1 - 1);
		strYear =
		    strDate.substr(nPos2 + 1, strDate.length() - nPos2 - 1);
		break;

	    case PixilDT::DATE_DYM:
		strDay = strDate.substr(0, nPos1);
		strYear = strDate.substr(nPos1 + 1, nPos2 - nPos1 - 1);
		strMonth =
		    strDate.substr(nPos2 + 1, strDate.length() - nPos2 - 1);
		break;

	    case PixilDT::DATE_MYD:
		strMonth = strDate.substr(0, nPos1);
		strYear = strDate.substr(nPos1 + 1, nPos2 - nPos1 - 1);
		strDay =
		    strDate.substr(nPos2 + 1, strDate.length() - nPos2 - 1);
		break;

	    case PixilDT::DATE_YMD:
		strYear = strDate.substr(0, nPos1);
		strMonth = strDate.substr(nPos1 + 1, nPos2 - nPos1 - 1);
		strDay =
		    strDate.substr(nPos2 + 1, strDate.length() - nPos2 - 1);
		break;

	    case PixilDT::DATE_YDM:
		strYear = strDate.substr(0, nPos1);
		strDay = strDate.substr(nPos1 + 1, nPos2 - nPos1 - 1);
		strYear =
		    strDate.substr(nPos2 + 1, strDate.length() - nPos2 - 1);
		break;

		//case PixilDT::DATE_MDY:
	    default:
		strMonth = strDate.substr(0, nPos1);
		strDay = strDate.substr(nPos1 + 1, nPos2 - nPos1 - 1);
		strYear =
		    strDate.substr(nPos2 + 1, strDate.length() - nPos2 - 1);
	    }
	}

	// Test each component for numerics
	if (::TestNumeric(strYear)
	    &&::TestNumeric(strMonth)
	    &&::TestNumeric(strDay)) {
	    static const int nMonthDays[2][12] = {
		{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
		{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
	    };
	    int nDay;
	    int nLeapYear;
	    int nMonth;
	    int nYear;

	    // Now test the range for each
	    nYear = atoi(strYear.c_str());

	    // Fix up a 2 digit year
	    if (nYear < 100) {
		if (nYear < 70) {
		    nYear += 2000;
		} else {
		    nYear += 1900;
		}
	    }
	    // Get the rest
	    nMonth = atoi(strMonth.c_str()) - 1;
	    nDay = atoi(strDay.c_str());
	    nLeapYear = ((nYear % 4) == 0);
	    if (nYear >= 1970 && nYear <= 2036
		&& nMonth >= 0 && nMonth <= 11
		&& nDay >= 1 && nDay <= nMonthDays[nLeapYear][nMonth]) {
		// The range check is good, get the seconds for this date
		nDate = MakeDate(nYear - 1900, nMonth, nDay);
		nReturn = 0;
	    } else {
		if (nYear >= 1970 && nYear <= 2036) {
		    nReturn = -1;
		} else if (nMonth >= 0 && nMonth <= 11) {
		    nReturn = -2;
		} else		//if (nDay>=1&&nDay<=nMonthDays[nLeapYear][nMonth])
		{
		    nReturn = -3;
		}
	    }
	} else {
	    if (!TestNumeric(strYear)) {
		nReturn = -4;
	    }
	    if (!TestNumeric(strMonth)) {
		nReturn = -5;
	    } else		//if (!TestNumeric(strDay))
	    {
		nReturn = -6;
	    }
	}
    } else if (strDate.length() == 0) {
	// Blank date = no date
	nDate = 0;
	nReturn = 0;
    } else {
	nReturn = -7;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Validate a newly entered time.  The entered time must be in  //
// a valid time in HH:MM (AM/PM), HH (AM/PM) or just HH format. //
// If the AM.PM string is missing then PM will be assumed.  The //
// returned value will be 0 if the date is valid or a negative  //
// number indicating the error type if the date is not valid.   //
//--------------------------------------------------------------//
int
ValidateTime(const char *pszTime, int &nTime)
{
    int nAmPm;
    int nHour;
    int nMinute;
    int nReturn = 0;
    string strAm;
    string strAmPm;
    string strHour;
    string strMinute;
    string strPm;
    string strTime = pszTime;
    unsigned int i;
    unsigned int nPos;

    // Determine the AM/PM strings
    PixilDT::GetAMPM(strAm, strPm);

    // Test the format - find the colon delimiter
    nPos = strTime.find(PixilDT::GetTimeSeparator(), 0);
    if (nPos == string::npos) {
	nPos = strTime.find(':', 0);
    }
    // Was any delimiter found ?
    if (nPos != string::npos) {
	// Get the hour
	strHour = strTime.substr(0, nPos);
	i = nPos + 1;
	while (i < strTime.length() && isdigit(strTime[i])) {
	    strMinute += strTime[i++];
	}
	strAmPm = strTime.substr(i, strTime.length() - i);
    } else {
	// No delimiter was found
	i = 0;
	while (i < strTime.length() && isdigit(strTime[i])) {
	    strHour += strTime[i++];
	}
	strAmPm = strTime.substr(i, strTime.length() - i);
    }

    // Validate the AM/PM field
    while (strAmPm.length() > 0 && isspace(strAmPm[0])) {
	strAmPm = strAmPm.substr(1, strAmPm.length() - 1);
    }
    while (strAmPm.length() > 0 && isspace(strAmPm[strAmPm.length() - 1])) {
	strAmPm = strAmPm.substr(0, strAmPm.length() - 1);
    }
    if (strAmPm.length() == 0) {
	nHour = atoi(strHour.c_str());
	if (strAm.length() != 0) {
	    // Twelve hour clock
	    if (nHour < 6 || nHour > 12) {
		// Assume that this PM
		nAmPm = 12 * 60 * 60;
	    } else {
		// Assume that this is AM
		nAmPm = 0;
	    }
	} else {
	    // 24 hour clock
	    nAmPm = 0;
	}
    } else if (strcasecmp(strAmPm.c_str(), strPm.c_str()) == 0) {
	nAmPm = 12 * 60 * 60;
    } else if (strcasecmp(strAmPm.c_str(), strAm.c_str()) == 0) {
	nAmPm = 0;
    } else {
	nReturn = -1;		// AM/PM indicator is invalid
    }

    // Continue if no errors
    if (nReturn == 0) {
	// Is everything else numeric
	if (::TestNumeric(strHour)
	    &&::TestNumeric(strHour)) {
	    nHour = atoi(strHour.c_str());
	    nMinute = atoi(strMinute.c_str());
	    if ((strAmPm.length() == 0 && nHour >= 0 && nHour <= 24)
		|| (strAmPm.length() > 0 && nHour >= 1 && nHour <= 12)) {
		// The hour is good, so far
		if (nMinute >= 0 && nMinute <= 59) {
		    // Don't allow minutes other than zero for last hour of 24 hour clock
		    if ((strAmPm.length() != 0 || nHour != 24
			 || nMinute != 0)) {
			// The minutes are good also, set up the time
			nTime = nAmPm + nHour * 60 * 60 + nMinute * 60;
			if (strAmPm.length() > 0 && nHour == 12) {
			    // Correct for 12:00 noon - 12:59 PM and 12:00 midnight - 12:59 AM
			    nTime -= 12 * 60 * 60;
			}
		    } else {
			nReturn = -2;	// Minutes too high for last hour of 24 hour clock
		    }
		} else {
		    nReturn = -3;	// Minutes must be between 0 and 59
		}
	    } else {
		if (strAmPm.length() == 0) {
		    nReturn = -4;	// The hour is out of range 0 through 24
		} else {
		    nReturn = -5;	// The hour is out of range 1 through 12
		}
	    }
	} else {
	    if (::TestNumeric(strHour) == false) {
		nReturn = -6;	// The hour is not numeric
	    } else		// if (::TestNumeric(strHour)==false)
	    {
		nReturn = -7;	// The minutes are not numeric
	    }
	}
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Determine the number of weeks between two dates.  The number //
// of weeks is calculated as the number of weeks between the    //
// two Sunday's prior to both dates.                            //
//--------------------------------------------------------------//
int
WeeksBetween(time_t nDate1, time_t nDate2)
{
    struct tm *pTm;

    // Don't need the Sunday prior to the first date

    // Get the Sunday prior to the second date
    pTm = localtime(&nDate2);
    nDate2 = SubtractDays(nDate2, pTm->tm_wday);

    // Get the difference in weeks
    return (DaysBetween(nDate1, nDate2) / 7);
}


//--------------------------------------------------------------//
// Determine the number of years between two dates.             //
//--------------------------------------------------------------//
int
YearsBetween(time_t nDate1, time_t nDate2)
{
    int nYear1;
    struct tm *pTm = localtime(&nDate1);

    nYear1 = pTm->tm_year;
    pTm = localtime(&nDate2);
    return (nYear1 - pTm->tm_year);
}

--- NEW FILE: Notes.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Center of the window for the Notes display                   //
//--------------------------------------------------------------//
#include "config.h"
#include <cassert>
#include <FL/fl_ask.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "Notes.h"
#include "NotesCategoryDB.h"
#include "Options.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Default constructor                                          //
//--------------------------------------------------------------//
Notes::Notes(Fl_Widget * pParent)
:  Fl_Group(pParent->x(), pParent->y(), pParent->w(), pParent->h())
{
    // Initialize these
    m_bUndoCut = false;
    m_bUndoPaste = false;

    // Reset the default color
    color(FL_GRAY);

    // Set up the details display, must be first as the list makes use of it during construction.
    m_pNoteDetails = new NoteDetails(x() + w() - DETAILS_WIDTH - DLG_BORDER,
				     y() + DLG_BORDER,
				     DETAILS_WIDTH, h() - 2 * DLG_BORDER);
    m_pNoteDetails->Enable(false);

    // Set up the title
    m_pTitle = new Fl_Box(x() + DLG_BORDER,
			  y() + DLG_BORDER,
			  PAGE_LABEL_WIDTH, DLG_BUTTON_HEIGHT);
    m_pTitle->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
    m_pTitle->label(_("Notes"));
    m_pTitle->box(FL_DOWN_BOX);
    m_pTitle->labelfont(FL_HELVETICA_BOLD);

    m_pCategory =
	new Fl_Choice(x() + w() - DETAILS_WIDTH - 2 * DLG_BORDER -
		      CATEGORY_CHOICE_WIDTH, y() + DLG_BORDER,
		      CATEGORY_CHOICE_WIDTH, DLG_BUTTON_HEIGHT);
    m_pCategoryMenu =
	NotesCategoryDB::GetNotesCategoryDB()->GetCategoryMenu(true);
    m_pCategory->menu(m_pCategoryMenu);
    m_pCategory->callback(CategorySelected);

    // Set up the list
    m_pNoteList = new NoteList(x() + DLG_BORDER,
			       y() + 2 * DLG_BORDER + DLG_BUTTON_HEIGHT,
			       w() - DETAILS_WIDTH - 3 * DLG_BORDER,
			       h() - 4 * DLG_BORDER - 2 * DLG_BUTTON_HEIGHT);
    m_pNoteList->color(FL_WHITE);

    // Set up the button
    m_pNewButton =
	new Fl_Button(x() + w() - (DLG_BUTTON_WIDTH + DLG_BORDER) -
		      DETAILS_WIDTH - DLG_BORDER,
		      y() + h() - (DLG_BORDER + DLG_BUTTON_HEIGHT),
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, _("&New"));
    m_pNewButton->callback(NewButton);
    end();

    // Set that the list area is resizable
    resizable(m_pNoteList);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
Notes::~Notes()
{
    FreeTranslatedMenu(m_pCategoryMenu);
}


//--------------------------------------------------------------//
// Category selection has been changed, filter the Notes        //
// entries                                                      //
//--------------------------------------------------------------//
void
Notes::CategorySelected(Fl_Widget * pWidget, void *pUserData)
{
    Notes *pThis = reinterpret_cast < Notes * >(pWidget->parent());

    // Save any changes
    pThis->SaveDetailChanges();

    // Filter rows based on category
    // Get the category value -1 so that -1 is the All category
    pThis->Filter((reinterpret_cast < Fl_Choice * >(pWidget))->value() - 1);
}


//--------------------------------------------------------------//
// Copy a row to m_strCopyString.                               //
//--------------------------------------------------------------//
int
Notes::Copy(int nRow)
{
    NoteDB *pNoteDB = NoteDB::GetNoteDB();
    int nReturn;

    if (nRow >= 0) {
	// Save any changes
	SaveDetailChanges();

	// Copy this row
	pNoteDB->Export(nRow, m_vCopyString);
	PixilDT::GetApp()->GetMainWindow()->Notify(FIX_MENU, 0);
	nReturn = 1;
    } else {
	// No row to copy
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Cut a row to m_strCopyString.                                //
//--------------------------------------------------------------//
int
Notes::Cut(int nRow)
{
    NoteDB *pNoteDB = NoteDB::GetNoteDB();
    int nReturn;

    if (nRow >= 0) {
	// Save any changes
	SaveDetailChanges();

	// Cut this row
	pNoteDB->Export(nRow, m_vCopyString);
	pNoteDB->Delete(nRow);
	pNoteDB->Save();
	m_bUndoCut = true;
	m_bUndoPaste = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(NOTES_CHANGED, 0);
	nReturn = 1;
    } else {
	// No row to copy
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Confirm the deletion of a Note.                              //
//--------------------------------------------------------------//
void
Notes::Delete(int nRow)
{
    NoteDB *pNoteDB = NoteDB::GetNoteDB();
    int nContinue;

    if (Options::GetConfirmDelete() == true) {
	nContinue = fl_ask(_("Delete Note: %s ?"),
			   pNoteDB->GetTitle(nRow).length() > 0
			   ? pNoteDB->GetTitle(nRow).c_str()
			   : _("(no title)"));
    } else {
	nContinue = 1;
    }

    if (nContinue == 1) {
	pNoteDB->Delete(nRow);
	pNoteDB->Save();
	PixilDT::GetApp()->GetMainWindow()->Notify(NOTES_CHANGED, 0);
    }
}


//--------------------------------------------------------------//
// Insert a new entry entry via the dialog.                     //
//--------------------------------------------------------------//
void
Notes::EditNew()
{
    int nCategory;
    int nRecno;
    int nRow;
    NoteDB *pNoteDB = NoteDB::GetNoteDB();
    NotesCategoryDB *pNotesCategoryDB = NotesCategoryDB::GetNotesCategoryDB();

    // Save any changes
    SaveDetailChanges();

    // Create a new note
    nCategory = m_pCategory->value() - 1;
    if (nCategory >= 0) {
	nCategory = pNotesCategoryDB->GetCategoryID(nCategory);
    } else {
	nCategory = 0;
    }
    nRow = pNoteDB->Insert(nCategory);
    nRecno = pNoteDB->GetIndex(nRow);

    // OK button was pressed, refresh displays
    PixilDT::GetApp()->GetMainWindow()->Notify(NOTES_CHANGED, 0);

    // Select the row just added or updated
    m_pNoteList->SelectRow(pNoteDB->FindRow(NOTE_INDEX, nRecno));
}


//--------------------------------------------------------------//
// Change any line with a category just deleted back to Unfiled //
//--------------------------------------------------------------//
void
Notes::FixDeletedCategory(int nCategory)
{
    NoteDB *pNoteDB = NoteDB::GetNoteDB();
    int nMax = pNoteDB->NumRecs();
    int nRow;

    for (nRow = 0; nRow < nMax; ++nRow) {
	if (pNoteDB->IsDeleted(nRow) == false) {
	    if (pNoteDB->GetCategory(nRow) == nCategory) {
		// "0" should be the "Unfiled" category
		pNoteDB->SetCategory(nRow, 0);
	    }
	}
    }
    pNoteDB->Save();
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
Notes::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case NOTES_CATEGORY_ADDED:
	// Fix and reset the category choice
	ResetCategoryChoice();
	break;

    case NOTES_CATEGORY_DELETED:
	// Fix all Notes entries with this category to be Unfiled
	FixDeletedCategory(nInfo);

	// Fix and reset the category choice
	ResetCategoryChoice();

	// Refresh the Note List
	m_pNoteList->Refresh();
	break;

    case NOTES_CATEGORY_RENAMED:
	// Fix and reset the category choice
	ResetCategoryChoice();

	// Refresh the Note List
	m_pNoteList->Refresh();
	break;

    case NOTES_CHANGED:	// Notes have been changed
	m_pNoteList->Refresh();
	break;

    case NOTES_DELETE:		// Delete the current item
	Delete(m_pNoteList->row());
	break;

    case NOTES_GOTO:		// Find dialog requested a note
	m_pNoteList->Message(nMessage, nInfo);
	break;

    case NOTES_NEW:		// Insertion of a new note has been requested
	EditNew();
	break;

    case NOTES_PRINT:		// Print the notes
	m_pNoteList->Print();
	break;

    case NOTES_REQUESTED:	// Selection changing back to notes, no processing needed
    case APPLICATION_CLOSING:	// No processing needed, already saved if need be
	break;

    case ADDRESS_BOOK_REQUESTED:	// Selection changing, save any outstanding updates
    case SCHEDULER_REQUESTED:	// Selection changing, save any outstanding updates
    case TODO_LIST_REQUESTED:	// Selection changing, save any outstanding updates
    case SELECTION_CHANGING:	// Save any outstanding updates
	nReturn = m_pNoteDetails->SaveChanges(true);
	break;

    case EDIT_COPY:		// Copy the currently selected line
	nReturn = Copy(m_pNoteList->row());
	break;

    case EDIT_CUT:		// Cut the currently selected line
	nReturn = Cut(m_pNoteList->row());
	break;

    case EDIT_PASTE:		// Paste a prior copy or cut
	nReturn = Paste();
	break;

    case EDIT_UNDO:		// Undo a prior cut/paste
	nReturn = Undo();
	break;

    case EDIT_COPY_AVAILABLE:	// Can a row be cut or copied
    case EDIT_CUT_AVAILABLE:
	nReturn = (m_pNoteList->rows() > 0 && m_pNoteList->row() >= 0);
	break;

    case EDIT_PASTE_AVAILABLE:	// Has a row been cut or copied
	nReturn = (m_vCopyString.size() > 0);
	break;

    case EDIT_UNDO_AVAILABLE:	// Can the last cut/paste be undone
	nReturn = (m_bUndoCut | m_bUndoPaste ? 1 : 0);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Paste the most recently cut row.                             //
//--------------------------------------------------------------//
int
Notes::Paste()
{
    NoteDB *pNoteDB = NoteDB::GetNoteDB();
    int nReturn;

    if (m_vCopyString.size() > 0) {
	// Save any changes
	SaveDetailChanges();

	m_nLastPaste = pNoteDB->Import(m_vCopyString);
	pNoteDB->Save();
	m_bUndoPaste = true;
	m_bUndoCut = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(NOTES_CHANGED, 0);
	nReturn = 1;
    } else {
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Reset the category choice widget after a category deletion.  //
//--------------------------------------------------------------//
void
Notes::ResetCategoryChoice()
{
    FreeTranslatedMenu(m_pCategoryMenu);
    m_pCategoryMenu =
	NotesCategoryDB::GetNotesCategoryDB()->GetCategoryMenu(true);
    m_pCategory->menu(m_pCategoryMenu);
}


//--------------------------------------------------------------//
// Undo the most recent cut or paste                            //
//--------------------------------------------------------------//
int
Notes::Undo()
{
    NoteDB *pNoteDB = NoteDB::GetNoteDB();
    int nReturn;

    if (m_bUndoCut == true) {
	// Save any changes
	SaveDetailChanges();

	// Insert this row back
	pNoteDB->Import(m_vCopyString);
	pNoteDB->Save();
	m_bUndoCut = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(NOTES_CHANGED, 0);
	nReturn = 1;
    } else if (m_bUndoPaste == true) {
	// Delete this row
	pNoteDB->Delete(m_nLastPaste);
	pNoteDB->Save();
	m_bUndoPaste = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(NOTES_CHANGED, 0);
	nReturn = 1;
    } else {
	nReturn = 0;
    }
    return (nReturn);
}

--- NEW FILE: NoteList.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the Notes List.                                    //
//--------------------------------------------------------------//
#ifndef NOTESLIST_H_

#define NOTESLIST_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include "Messages.h"
#include "NoteDB.h"
#include "TableBase.h"
class NoteList:public TableBase
{
  public:NoteList(int nX,	// Constructor
	     int nY, int nWidth, int nHeight);
     ~NoteList();		// Destructor
    void Filter(int nCategory);	// Filter the displayed rows by category (-1 = all categories)
    int Message(PixilDTMessage nMessage,	// Process a message from the parent widget
		int nInfo);
    void Print();		// Print the notes
    void Refresh(int nID = -1);	// Refresh this list
    void SelectRow(int nRow);	// Select a row in the list and inform the parent of the selection
  protected:void CalculateColumnWidths(int nWidth);
    // Recalculate column widths
    void DoubleClick(int nRow,	// Process a double click over a row
		     int nCol);
    Fl_Pixmap *GetIconValue(int nRow,	// Get the icon for an icon column
			    int nCol);
    string GetStringValue(int nRow,	// Get the value of a column
			  int nCol);
    void IconClick(int nRow,	// Process a left mouse click over an icon column
		   int nCol);
    void LeftClick(int nRow,	// Process a left mouse click over a non-icon column
		   int nCol);
    void RightClick(int nRow,	// Process a right mouse click anywhere
		    int nCol);
  private:static const bool m_bIconColumns[2];
    // Small icon columns
    Fl_Pixmap *m_pNotesIcon;	// Notes icon used by all rows
    int m_nCategory;		// Category used for filtering (-1 for all)
    static int m_nSortCategory;	// Category used for filtering (-1 for all) during sorting
    static bool SortCategory(NxDbRow * pRow1,	// Sort by note title and filter by category
			     NxDbRow * pRow2);
    static bool SortCompare(NxDbRow * pRow1,	// Sort by note title
			    NxDbRow * pRow2);
};


#endif /*  */

--- NEW FILE: AddressBook.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Center of the window for the Address Book display            //
//--------------------------------------------------------------//
#ifdef WIN32
#pragma warning(disable:4786)
#endif
#include "config.h"
#include <cassert>
#include <FL/fl_ask.H>
#include "AddressBook.h"
#include "AddressBookCategoryDB.h"
#include "AddressBookDB.h"
#include "AddressBookDlg.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "ListByDlg.h"
#include "Options.h"
#include "PixilDT.h"

#include "VCMemoryLeak.h"


#define SEARCH_PROMPT   80

#define LIST_TOP_BORDER (TITLE_HEIGHT+2*DLG_BORDER)


//--------------------------------------------------------------//
// Default constructor                                          //
//--------------------------------------------------------------//
AddressBook::AddressBook(Fl_Widget * pParent)
:  Fl_Group(pParent->x(), pParent->y(), pParent->w(), pParent->h())
{
    // Initialize these
    m_bUndoCut = false;
    m_bUndoPaste = false;

    // Set up the details display, must be first as the list makes use of it during construction.
    m_pAddressBookDetails =
	new AddressBookDetails(x() + w() - DETAILS_WIDTH - DLG_BORDER,
			       y() + DLG_BORDER, DETAILS_WIDTH,
			       h() - 2 * DLG_BORDER);

    // Set up the title
    m_pTitle = new Fl_Box(x() + DLG_BORDER,
			  y() + DLG_BORDER,
			  PAGE_LABEL_WIDTH, DLG_BUTTON_HEIGHT);
    m_pTitle->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
    m_pTitle->label(_("Address"));
    m_pTitle->box(FL_DOWN_BOX);
    m_pTitle->labelfont(FL_HELVETICA_BOLD);

    m_pCategory =
	new Fl_Choice(x() + w() - DETAILS_WIDTH - 2 * DLG_BORDER -
		      CATEGORY_CHOICE_WIDTH, y() + DLG_BORDER,
		      CATEGORY_CHOICE_WIDTH, DLG_BUTTON_HEIGHT);
    m_pCategoryMenu =
	AddressBookCategoryDB::GetAddressBookCategoryDB()->
	GetCategoryMenu(true);
    m_pCategory->menu(m_pCategoryMenu);
    m_pCategory->callback(CategorySelected);

    // Set up the list
    m_pAddressBookList = new AddressBookList(x() + DLG_BORDER,
					     y() + 2 * DLG_BORDER +
					     DLG_BUTTON_HEIGHT,
					     w() - DETAILS_WIDTH -
					     3 * DLG_BORDER,
					     h() - 5 * DLG_BORDER -
					     3 * DLG_BUTTON_HEIGHT, false);
    m_pAddressBookList->color(FL_WHITE);

    // Set up the search string
    m_pSearch = new InputNotify(x() + DLG_BORDER + SEARCH_PROMPT,
				y() + h() - 2 * (DLG_BORDER +
						 DLG_BUTTON_HEIGHT),
				w() - DETAILS_WIDTH - 3 * DLG_BORDER -
				SEARCH_PROMPT, DLG_BUTTON_HEIGHT,
				_("Search:"), SearchEntered);

    // Set up the buttons
    m_pListByButton =
	new Fl_Button(x() + w() - 3 * (DLG_BUTTON_WIDTH + DLG_BORDER) -
		      DETAILS_WIDTH - DLG_BORDER,
		      y() + h() - (DLG_BORDER + DLG_BUTTON_HEIGHT),
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, _("&List By"));
    m_pListByButton->callback(ListByButton);
    m_pEditButton =
	new Fl_Button(x() + w() - 2 * (DLG_BUTTON_WIDTH + DLG_BORDER) -
		      DETAILS_WIDTH - DLG_BORDER,
		      y() + h() - (DLG_BORDER + DLG_BUTTON_HEIGHT),
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, _("&Edit"));
    m_pEditButton->callback(EditButton);
    m_pNewButton =
	new Fl_Button(x() + w() - (DLG_BUTTON_WIDTH + DLG_BORDER) -
		      DETAILS_WIDTH - DLG_BORDER,
		      y() + h() - (DLG_BORDER + DLG_BUTTON_HEIGHT),
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, _("&New"));
    m_pNewButton->callback(NewButton);
    end();

    // Set that the list area is resizable
    resizable(m_pAddressBookList);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
AddressBook::~AddressBook()
{
    FreeTranslatedMenu(m_pCategoryMenu);
}


//--------------------------------------------------------------//
// Category selection has been changed, filter the Address Book //
// entries                                                      //
//--------------------------------------------------------------//
void
AddressBook::CategorySelected(Fl_Widget * pWidget, void *pUserData)
{
    AddressBook *pThis =
	reinterpret_cast < AddressBook * >(pWidget->parent());

    // Filter rows based on category
    // Get the category value -1 so that -1 is the All category
    pThis->Filter((reinterpret_cast < Fl_Choice * >(pWidget))->value() - 1);
}


//--------------------------------------------------------------//
// Copy a row to m_strCopyString.                               //
//--------------------------------------------------------------//
int
AddressBook::Copy(int nRow)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int nReturn;

    if (nRow >= 0) {
	// Copy this row
	pAddressBookDB->Export(nRow, m_vCopyString);
	PixilDT::GetApp()->GetMainWindow()->Notify(FIX_MENU, 0);
	nReturn = 1;
    } else {
	// No row to copy
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Cut a row to m_strCopyString.                                //
//--------------------------------------------------------------//
int
AddressBook::Cut(int nRow)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int nReturn;

    if (nRow >= 0) {
	// Copy this row
	pAddressBookDB->Export(nRow, m_vCopyString);
	pAddressBookDB->Delete(nRow);
	pAddressBookDB->Save();
	m_bUndoCut = true;
	m_bUndoPaste = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);
	nReturn = 1;
    } else {
	// No row to copy
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Confirm the deletion of a row in the address book.           //
//--------------------------------------------------------------//
void
AddressBook::Delete(int nRow)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int nContinue;

    if (Options::GetConfirmDelete() == true) {
	nContinue = fl_ask(_("Delete Address for %s %s ?"),
			   pAddressBookDB->GetFirstName(nRow).c_str(),
			   pAddressBookDB->GetLastName(nRow).c_str());
    } else {
	nContinue = 1;
    }

    if (nContinue == 1) {
	pAddressBookDB->Delete(nRow);
	pAddressBookDB->Save();
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);
    }
}


//--------------------------------------------------------------//
// Edit a row in the address book.                              //
//--------------------------------------------------------------//
void
AddressBook::Edit(int nRow)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    AddressBookDlg *pAddressBookDlg;

#ifdef DEBUG
    printf("nRow = %d rows = %d", nRow, m_pAddressBookList->rows());
    //  assert(nRow>=0&&nRow<m_pAddressBookList->rows());
#endif

    pAddressBookDlg =
	new AddressBookDlg(nRow, PixilDT::GetApp()->GetMainWindow());
    if (pAddressBookDlg->DoModal() == 1) {
	// OK button was pressed, refresh displays
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);

	// Select the row just added or updated
	m_pAddressBookList->SelectRow(pAddressBookDB->
				      FindRecno(pAddressBookDlg->GetRecno()));
    }
    delete pAddressBookDlg;
}


//--------------------------------------------------------------//
// Edit button callback (static).                               //
//--------------------------------------------------------------//
void
AddressBook::EditButton(Fl_Widget * pWidget, void *pUserData)
{
    AddressBook *pThis =
	reinterpret_cast < AddressBook * >(pWidget->parent());

    pThis->Edit(pThis->m_pAddressBookList->GetRealRow());
}


//--------------------------------------------------------------//
// Insert a new address book entry via the dialog.              //
//--------------------------------------------------------------//
void
AddressBook::EditNew()
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    AddressBookDlg *pAddressBookDlg =
	new AddressBookDlg(-1, PixilDT::GetApp()->GetMainWindow());

    if (pAddressBookDlg->DoModal() == 1) {
	// OK button was pressed, refresh displays
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);

	// Select the row just added or updated
	m_pAddressBookList->SelectRow(pAddressBookDB->
				      FindRecno(pAddressBookDlg->GetRecno()));
    }
    delete pAddressBookDlg;
}


//--------------------------------------------------------------//
// Change any line with a category just deleted back to Unfiled //
//--------------------------------------------------------------//
void
AddressBook::FixDeletedCategory(int nCategory)
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int nMax = pAddressBookDB->NumRecs();
    int nRow;

    for (nRow = 0; nRow < nMax; ++nRow) {
	if (pAddressBookDB->IsDeleted(nRow) == false) {
	    if (pAddressBookDB->GetCategory(nRow) == nCategory) {
		// "0" should be the "Unfiled" category
		pAddressBookDB->SetCategory(nRow, 0);
	    }
	}
    }
    pAddressBookDB->Save();
}


//--------------------------------------------------------------//
// Process a click on the List By button.                       //
//--------------------------------------------------------------//
void
AddressBook::ListByButton(Fl_Widget * pWidget, void *pUserData)
{
    AddressBook *pThis =
	reinterpret_cast < AddressBook * >(pWidget->parent());

    pThis->ShowListByDialog();
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
AddressBook::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case ADDRESS_BOOK_CATEGORY_ADDED:
	// Fix and reset the category choice
	ResetCategoryChoice();
	break;

    case ADDRESS_BOOK_CATEGORY_DELETED:
	// Fix all Address Book entries with this category to be Unfiled
	FixDeletedCategory(nInfo);

	// Fix and reset the category choice
	ResetCategoryChoice();

	// Refresh the Address Book List
	m_pAddressBookList->Refresh();
	break;

    case ADDRESS_BOOK_CATEGORY_RENAMED:
	// Fix and reset the category choice
	ResetCategoryChoice();

	// Refresh the Address Book List
	m_pAddressBookList->Refresh();
	break;

    case ADDRESS_BOOK_CHANGED:	// The selection has moved to a different row
	m_pAddressBookDetails->Message(nMessage, 0);
	m_pAddressBookList->Message(nMessage, 0);
	break;

    case ADDRESS_BOOK_DELETE:	// Delete the current item
	Delete(m_pAddressBookList->GetRealRow());
	break;

    case ADDRESS_BOOK_GOTO:	// Display a particular line
	m_pAddressBookList->Message(nMessage, nInfo);
	break;

    case ADDRESS_BOOK_NEW:	// Insertion of a new address book entry has been requested
	EditNew();
	break;

    case ADDRESS_BOOK_PRINT:	// Print the address book as currently sorted
	m_pAddressBookList->Print();
	break;

    case SHOW_LIST_BY:		// Show the List By dialog
	ShowListByDialog();
	break;

    case SELECTION_CHANGING:	// No processing needed here
	nReturn = 1;		// Indicate that no errors occurred
	break;

    case ADDRESS_BOOK_REQUESTED:	// Selection changing, no processing needed
    case NOTES_REQUESTED:	// Selection changing, no processing needed
    case SCHEDULER_REQUESTED:	// Selection changing, no processing needed
    case TODO_LIST_REQUESTED:	// Selection changing, no processing needed
    case APPLICATION_CLOSING:	// No processing needed here
	break;

    case EDIT_COPY:		// Copy the currently selected line
	nReturn = Copy(m_pAddressBookList->GetRealRow());
	break;

    case EDIT_CUT:		// Cut the currently selected line
	nReturn = Cut(m_pAddressBookList->GetRealRow());
	break;

    case EDIT_PASTE:		// Paste a prior copy or cut
	nReturn = Paste();
	break;

    case EDIT_UNDO:		// Undo a prior cut/paste
	nReturn = Undo();
	break;

    case EDIT_COPY_AVAILABLE:	// Can a row be cut or copied
    case EDIT_CUT_AVAILABLE:
	nReturn = (m_pAddressBookList->rows() > 0
		   && m_pAddressBookList->row() >= 0);
	break;

    case EDIT_PASTE_AVAILABLE:	// Has a row been cut or copied
	nReturn = (m_vCopyString.size() > 0);
	break;

    case EDIT_UNDO_AVAILABLE:	// Can the last cut/paste be undone
	nReturn = (m_bUndoCut | m_bUndoPaste ? 1 : 0);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Paste the most recently cut row.                             //
//--------------------------------------------------------------//
int
AddressBook::Paste()
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int nReturn;

    if (m_vCopyString.size() > 0) {
	m_nLastPaste = pAddressBookDB->Import(m_vCopyString);
	pAddressBookDB->Save();
	m_bUndoPaste = true;
	m_bUndoCut = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);
	nReturn = 1;
    } else {
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Reset the category choice widget after a category deletion.  //
//--------------------------------------------------------------//
void
AddressBook::ResetCategoryChoice()
{
    FreeTranslatedMenu(m_pCategoryMenu);
    m_pCategoryMenu =
	AddressBookCategoryDB::GetAddressBookCategoryDB()->
	GetCategoryMenu(true);
    m_pCategory->menu(m_pCategoryMenu);
}


//--------------------------------------------------------------//
// Pseudo callback from an InputNotify object that its text has //
// changed.                                                     //
//--------------------------------------------------------------//
void
AddressBook::SearchEntered(Fl_Widget * pWidget, void *pUserData)
{
    AddressBook *pThis = reinterpret_cast < AddressBook * >(pWidget);

    if (pThis->m_pAddressBookList->Search(pThis->m_pSearch->value()) == false) {
	string strValue = pThis->m_pSearch->value();

	if (strValue.length() > 1) {
	    strValue = strValue.substr(0, strValue.length() - 1);
	} else {
	    strValue = "";
	}
	pThis->m_pSearch->value(strValue.c_str());
    }
}


//--------------------------------------------------------------//
// Show the List By dialog                                      //
//--------------------------------------------------------------//
void
AddressBook::ShowListByDialog()
{
    ListByDlg *pDlg = new ListByDlg(m_pAddressBookList->GetListBy(),
				    PixilDT::GetApp()->GetMainWindow());

    if (pDlg->DoModal() == 1) {
	// OK button was pressed
	m_pAddressBookList->SetListBy(pDlg->GetSelection());
	m_pAddressBookList->Refresh();
    }
    delete pDlg;
}


//--------------------------------------------------------------//
// Undo the most recent cut or paste                            //
//--------------------------------------------------------------//
int
AddressBook::Undo()
{
    AddressBookDB *pAddressBookDB = AddressBookDB::GetAddressBookDB();
    int nReturn;

    if (m_bUndoCut == true) {
	// Insert this row back
	pAddressBookDB->Import(m_vCopyString);
	pAddressBookDB->Save();
	m_bUndoCut = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);
	nReturn = 1;
    } else if (m_bUndoPaste == true) {
	// Delete this row
	pAddressBookDB->Delete(m_nLastPaste);
	pAddressBookDB->Save();
	m_bUndoPaste = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(ADDRESS_BOOK_CHANGED, 0);
	nReturn = 1;
    } else {
	nReturn = 0;
    }
    return (nReturn);
}

--- NEW FILE: CategoryDBDef.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Base category database definition fields.                    //
//--------------------------------------------------------------//
#ifndef CATEGORYDBDEF_H_

#define CATEGORYDBDEF_H_

// Category List
field catFields[] = {
    {
     'i', 1, 0}
    ,				// Field 0:catid
    {
     'c', 1, 0}
    ,				//              1:cat_name (length will be set later
    {
     0}
};


// Database
fildes catFile = {
    0, 0, 0, "dbf", 2, &catFields[0]
};


#endif /*  */

--- NEW FILE: SchedulerMonthly.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler Monthly tab page                                   //
//--------------------------------------------------------------//
#include "config.h"
#include <cassert>
#include <climits>
#include <FL/Fl.H>
#include <FL/forms.H>

#include "DatePickerDlg.h"
#include "Dialog.h"
#include "FLTKUtil.h"
#include "Images.h"
#include "Options.h"
#include "PixilDT.h"
#include "Printer.h"
#include "SchedulerDB.h"
#include "SchedulerMonthly.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


using namespace std;


#define BUTTON_BORDER 2


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
SchedulerMonthly::SchedulerMonthly(int nX, int nY, int nWidth, int nHeight)
    :
Fl_Group(nX, nY, nWidth, nHeight, _("Monthly"))
{
    Fl_Group *pGroup;
    int i;
    int j;
    int nDayHeight;
    int nDayWidth;
    int nGroupHeight;
    int nGroupWidth;
    int nGroupX;
    int nGroupY;
    int nWeekBegins = Options::GetWeekBegins();

    // Create the top line of the page, in a group for resizing
    pGroup = new Fl_Group(x() + DLG_BORDER,
			  y() + DLG_BORDER,
			  w() - 2 * DLG_BORDER, DLG_INPUT_HEIGHT);
    nGroupX = pGroup->x();
    nGroupY = pGroup->y();
    nGroupWidth = pGroup->w();
    m_pLeftButton = new Fl_Button(nGroupX,
				  nGroupY,
				  IMAGE_BUTTON_WIDTH, DLG_INPUT_HEIGHT);
    m_pLeftPixmap = Images::GetBigLeftIcon();
    m_pLeftPixmap->label(m_pLeftButton);
    m_pLeftButton->callback(OnLeftButton);
    m_pGoToButton =
	new Fl_Button(nGroupX + IMAGE_BUTTON_WIDTH + BUTTON_BORDER, nGroupY,
		      DLG_BUTTON_WIDTH, DLG_INPUT_HEIGHT, _("&Go To"));
    m_pGoToButton->callback(OnGotoButton);
    m_pRightButton =
	new Fl_Button(nGroupX + IMAGE_BUTTON_WIDTH + 2 * BUTTON_BORDER +
		      DLG_BUTTON_WIDTH, nGroupY, IMAGE_BUTTON_WIDTH,
		      DLG_INPUT_HEIGHT);
    m_pRightPixmap = Images::GetBigRightIcon();
    m_pRightPixmap->label(m_pRightButton);
    m_pRightButton->callback(OnRightButton);
    m_pDate =
	new Fl_Box(nGroupX + DLG_BORDER + 2 * IMAGE_BUTTON_WIDTH +
		   2 * BUTTON_BORDER + DLG_BUTTON_WIDTH, nGroupY,
		   nGroupWidth - 2 * DLG_BORDER - 2 * IMAGE_BUTTON_WIDTH -
		   2 * BUTTON_BORDER - 2 * DLG_BUTTON_WIDTH,
		   DLG_INPUT_HEIGHT);
    m_pDate->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
    m_pDate->box(FL_DOWN_BOX);
    m_pDate->color(FL_WHITE);
    m_pTodayButton = new Fl_Button(nGroupX + nGroupWidth - DLG_BUTTON_WIDTH,
				   nGroupY,
				   DLG_BUTTON_WIDTH,
				   DLG_INPUT_HEIGHT, _("&Today"));
    m_pTodayButton->callback(OnTodayButton);
    pGroup->end();
    pGroup->resizable(m_pDate);

    // Create the day-of-week title boxes
    nDayWidth = (w() - 2 * DLG_BORDER - Fl::box_dw(FL_DOWN_BOX)) / 7;
    for (i = 0; i < 7; ++i) {
	m_pDow[i] =
	    new Fl_Box(x() + DLG_BORDER + (Fl::box_dw(FL_DOWN_BOX) >> 1) +
		       i * nDayWidth, y() + 2 * DLG_BORDER + DLG_INPUT_HEIGHT,
		       (i ==
			6 ? w() - 2 * DLG_BORDER - Fl::box_dw(FL_DOWN_BOX) -
			6 * nDayWidth : nDayWidth), DLG_INPUT_HEIGHT);
	m_pDow[i]->labelfont(FL_HELVETICA_BOLD);
	m_pDow[i]->labelsize((4 * labelsize()) / 5);
	m_pDow[i]->box(FL_FLAT_BOX);
	m_strDow[i] =::GetDayOfWeek((i + nWeekBegins) % 7);
	m_pDow[i]->label(m_strDow[i].c_str());
    }

    // Create the day boxes
    pGroup = new Fl_Group(x() + DLG_BORDER,
			  y() + 2 * DLG_BORDER + 2 * DLG_INPUT_HEIGHT,
			  w() - 2 * DLG_BORDER,
			  h() - 3 * DLG_BORDER - 2 * DLG_INPUT_HEIGHT);
    pGroup->box(FL_DOWN_BOX);
    resizable(pGroup);
    nGroupX = pGroup->x();
    nGroupY = pGroup->y();
    nGroupWidth = pGroup->w();
    nGroupHeight = pGroup->h();
    nDayHeight = (nGroupHeight - Fl::box_dh(FL_DOWN_BOX)) / 6;
    for (i = 0; i < 6; ++i) {
	for (j = 0; j < 7; ++j) {
	    m_pDay[i][j] =
		new Fl_Browser(nGroupX + (Fl::box_dw(FL_DOWN_BOX) >> 1) +
			       j * nDayWidth,
			       nGroupY + (Fl::box_dh(FL_DOWN_BOX) >> 1) +
			       i * nDayHeight,
			       (j ==
				6 ? nGroupWidth - Fl::box_dw(FL_DOWN_BOX) -
				6 * nDayWidth : nDayWidth),
			       (i ==
				5 ? nGroupHeight - Fl::box_dh(FL_DOWN_BOX) -
				5 * nDayHeight : nDayHeight));
	    m_pDay[i][j]->box(FL_BORDER_BOX);
	}
    }

    // Finish with this widget
    end();

    // Go display today's date
    DisplayDay(time(NULL));
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
SchedulerMonthly::~SchedulerMonthly()
{
    delete m_pLeftPixmap;
    delete m_pRightPixmap;
}


//--------------------------------------------------------------//
// Build the display for a date.                                //
//--------------------------------------------------------------//
void
SchedulerMonthly::BuildDate(time_t nDate, int nDayNo)
{
    char szString[16];
    Fl_Browser *pBrowser;
    int nMaxWidth;
    int nRow;
    multimap < int, int >::iterator iter;
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();
    string strText;
    string strText2;
    time_t nToday =::NormalizeDate(time(NULL));
    struct tm *pTm;

    // Clear the old contents
    pBrowser = m_pDay[nDayNo / 7][nDayNo % 7];
    pBrowser->clear();

    // Set the maximum width for a title
    nMaxWidth = pBrowser->w() - 20;	// 20 is a guess at a scrollbar width

    // Get the day of month for this day
    pTm = localtime(&nDate);
    strText = "@r at C";
    sprintf(szString, "%d", (nDate == nToday ? FL_RED : FL_BLACK));
    strText += szString;
    strText += "@.";
    sprintf(szString, "%d", pTm->tm_mday);
    strText += szString;
    pBrowser->add(strText.c_str());

    // Now add each event to the browser in order
    for (iter = m_pmEvent[nDayNo].begin(); iter != m_pmEvent[nDayNo].end();
	 ++iter) {
	nRow = iter->second;
	strText = pSchedulerDB->GetStartTimeString(nRow);
	strText += ' ';
	strText += pSchedulerDB->GetDescription(nRow);
	strText = WrapText(strText.c_str(), nMaxWidth, pBrowser);
	strText2 = "@.";
	strText2 += strText;
	pBrowser->add(strText2.c_str());
    }
}


//--------------------------------------------------------------//
// Display a particular day.                                    //
//--------------------------------------------------------------//
void
SchedulerMonthly::DisplayDay(time_t nDate)
{
    char szString[16];
    int i;
    int j;
    int nDays;
    int nMonth;
    int nWeekBegins = Options::GetWeekBegins();
    time_t nStartDate;
    time_t nToday =::NormalizeDate(time(NULL));
    struct tm *pTm;

    // Get the Sunday or Monday prior to the requested date
    pTm = localtime(&nDate);
    pTm->tm_isdst = -1;
    pTm->tm_sec = 0;
    pTm->tm_min = 0;
    pTm->tm_hour = 0;
    pTm->tm_mday = 1;
    m_nDate = mktime(pTm);
    nMonth = pTm->tm_mon;
    pTm = localtime(&m_nDate);
    nDays = pTm->tm_wday - nWeekBegins;
    if (nDays < 0) {
	nDays += 7;
    }
    nStartDate =::SubtractDays(m_nDate, nDays);

    // Fix the banner title's label
    pTm = localtime(&m_nDate);
    m_strDateLabel =::GetMonthName(m_nDate);
    sprintf(szString, " %d", pTm->tm_year + 1900);
    m_strDateLabel += szString;
    m_pDate->label(m_strDateLabel.c_str());

    // Get the events for each browser
    SchedulerDB::GetSchedulerDB()->GetEvents(m_pmEvent, nStartDate, 6 * 7);

    // Refresh each browser
    nDate = nStartDate;
    for (i = 0; i < 6; ++i) {
	for (j = 0; j < 7; ++j) {
	    pTm = localtime(&nDate);
	    m_pDay[i][j]->color(pTm->tm_mon == nMonth ? FL_WHITE : FL_GRAY);
	    BuildDate(nDate, i * 7 + j);
	    nDate =::AddDays(nDate, 1);
	}
    }

    // Enable or disable the Today button based on what day is being shown
    pTm = localtime(&nToday);
    pTm->tm_isdst = -1;
    pTm->tm_sec = 0;
    pTm->tm_min = 0;
    pTm->tm_hour = 0;
    pTm->tm_mday = 1;
    nToday = mktime(pTm);
    if (nToday == m_nDate) {
	m_pTodayButton->deactivate();
    } else {
	m_pTodayButton->activate();
    }

    // Redraw the entire widget
    redraw();
}


//--------------------------------------------------------------//
// Handle a double click by going to that day.                  //
//--------------------------------------------------------------//
int
SchedulerMonthly::handle(int nEvent)
{
    bool bFound = false;
    int i;
    int j;
    int nReturn;
    time_t nDate;

    // Tell Fl_Group about the event
    nReturn = Fl_Group::handle(nEvent);

    // Process here if a left mouse double click
    if (nEvent == FL_PUSH
	&& Fl::event_button() == FL_LEFT_MOUSE && Fl::event_clicks() > 0) {
	// Select this day and go to it
	for (i = 0; i < 6; ++i) {
	    for (j = 0; j < 7; ++j) {
		if (Fl::event_inside(m_pDay[i][j])) {
		    bFound = true;
		    break;
		}
	    }

	    // Break out if found
	    if (bFound == true) {
		break;
	    }
	}

	// Was this click in a day
	if (i < 6 && j < 7) {
	    // Go to this day, calculate the date
	    nDate =::AddDays(m_nDate,
			     i * 7 + j -::GetDow(m_nDate) +
			     Options::GetWeekBegins());
	    ((Scheduler *) (parent()->parent()))->SelectDay(nDate);
	}
	// Indicate that this event was processed
	nReturn = 1;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
SchedulerMonthly::Message(PixilDTMessage nMessage, int nInfo)
{
    int i;
    int nReturn = 0;		// Default return value
    int nWeekBegins;

    switch (nMessage) {
    case BEGIN_WEEK_CHANGED:	// Beginning day of week has been changed
	nWeekBegins = Options::GetWeekBegins();
	for (i = 0; i < 7; ++i) {
	    m_strDow[i] =::GetDayOfWeek((i + nWeekBegins) % 7);
	    m_pDow[i]->label(m_strDow[i].c_str());
	}
	DisplayDay(m_nDate);
	break;

    case SCHEDULER_CHANGED:	// Scheduler data changed, go refresh the display
	DisplayDay(m_nDate);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Process a click on the goto button.                          //
//--------------------------------------------------------------//
void
SchedulerMonthly::OnGotoButton(Fl_Widget * pWidget, void *pUserData)
{
    DatePickerDlg *pDlg;
    SchedulerMonthly *pThis =
	reinterpret_cast < SchedulerMonthly * >(pWidget->parent()->parent());

    pDlg = new DatePickerDlg(pThis->m_nDate,
			     DatePicker::Monthly,
			     PixilDT::GetApp()->GetMainWindow());
    if (pDlg->DoModal() == 1) {
	// The OK button was pressed, refresh this display
	pThis->DisplayDay(pDlg->GetDate());
    }
    // Clean up
    delete pDlg;
}


//--------------------------------------------------------------//
// Process a click on the left button.                          //
//--------------------------------------------------------------//
void
SchedulerMonthly::OnLeftButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerMonthly *pThis =
	reinterpret_cast < SchedulerMonthly * >(pWidget->parent()->parent());
    struct tm *pTm;

    // Only go left if not at beginning of the possible time range
    if (pThis->m_nDate > 31 * 24 * 60 * 60) {
	pTm = localtime(&pThis->m_nDate);
	pTm->tm_isdst = -1;
	--pTm->tm_mon;
	if (pTm->tm_mon < 0) {
	    pTm->tm_mon = 11;
	    --pTm->tm_year;
	}
	pThis->DisplayDay(mktime(pTm));
    }
}


//--------------------------------------------------------------//
// Process a click on the right button.                         //
//--------------------------------------------------------------//
void
SchedulerMonthly::OnRightButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerMonthly *pThis =
	reinterpret_cast < SchedulerMonthly * >(pWidget->parent()->parent());
    struct tm *pTm;

    // Only go right if not at end of the possible time range
    if (pThis->m_nDate <= LONG_MAX - (30 + 31) * 24 * 60 * 60) {
	pTm = localtime(&pThis->m_nDate);
	pTm->tm_isdst = -1;
	++pTm->tm_mon;
	if (pTm->tm_mon > 11) {
	    pTm->tm_mon = 0;
	    ++pTm->tm_year;
	}
	pThis->DisplayDay(mktime(pTm));
    }
}


//--------------------------------------------------------------//
// Process a click on the Today button.  The button is within a //
// group within this page hence the parent()->parent() to get   //
// to this object.                                              //
//--------------------------------------------------------------//
void
SchedulerMonthly::OnTodayButton(Fl_Widget * pWidget, void *pUserData)
{
    SchedulerMonthly *pThis =
	reinterpret_cast < SchedulerMonthly * >(pWidget->parent()->parent());

    // Go display the current date
    pThis->DisplayDay(time(NULL));
}


//--------------------------------------------------------------//
// Print this data.                                             //
//--------------------------------------------------------------//
void
SchedulerMonthly::Print()
{
    bool bOverflow;
    double fBoxHeight;
    double fBoxWidth;
    int nBorder = INCH / 2;	// 1/2 inch border
    int nCol;
    int nCopy;
    int nHeight;
    int nLastX;
    int nLastY;
    int nMonth;
    int nRow;
    int nX;
    int nY;
    multimap < int, int >mapEvent;
    multimap < int, int >::iterator iter;
    Printer printer;
    SchedulerDB *pSchedulerDB = SchedulerDB::GetSchedulerDB();
    string strData;
    string strKey;
    string strTrailer;
    time_t nDate;
    time_t nNow = time(NULL);
    time_t nTime;
    time_t nToday;
    struct tm *pTm;
    vector < string > vDescription;
    vector < string > vTime;
    vector < string > vShortTime;
    vector < time_t > vDate;
    vector < vector < string > >vvDescription;
    vector < vector < string > >vvTime;

    // Open the printer
    if (printer.Open(_("SchedulerMonthly")) == true) {
	// Set an hourglass cursor
	PixilDT::GetApp()->GetMainWindow()->SetCursor(FL_CURSOR_WAIT);

	// Print once for eqch requested copy
	for (nCopy = 0; nCopy < printer.GetCopies(); ++nCopy) {
	    // Reset the page number
	    printer.ResetPageNumber();

	    // Start the first page
	    printer.StartPage();

	    // Set up the title for the page
	    printer.SetBoldSerifFont(18);
	    nHeight =
		printer.GetHeight() - (3 * printer.GetFontSize() / 2) -
		nBorder;
	    printer.DrawText(0, nHeight, printer.GetWidth(),
			     3 * printer.GetFontSize() / 2,
			     FormatMonth(m_nDate).c_str(), FL_ALIGN_TOP);
	    nHeight -= printer.GetFontSize() / 2;

	    // Set the default font size
	    printer.SetSerifFont(8);

	    // Calculate the sizeof the calendar boxes
	    fBoxHeight =
		(double (nHeight - (3 * printer.GetFontSize()) / 2 - nBorder))
		/6.0;
	    fBoxWidth = (double (printer.GetWidth() - 2 * nBorder)) /7.0;

	    // Draw the day names
	    for (nCol = 0; nCol < 7; ++nCol) {
		printer.DrawText(int (nCol * fBoxWidth + nBorder),
				 nHeight,
				 int (fBoxWidth),
				 2 * printer.GetFontSize(),
				 GetDayOfWeek((nCol +
					       Options::GetWeekBegins()) %
					      7).c_str(), FL_ALIGN_TOP);
	    }

	    // Calculate the starting day for the calendar
	    nDate =::SubtractDays(m_nDate,
				  (7 +::GetDow(m_nDate) -
				   Options::GetWeekBegins()) % 7);

	    // Get the current month
	    pTm = localtime(&m_nDate);
	    nMonth = pTm->tm_mon;

	    // Get today's date
	    nToday =::NormalizeDate(time(NULL));

	    // Draw the calendar boxes
	    printer.CalendarStart(vDate, vvTime, vvDescription);
	    nLastY = nHeight;
	    for (nRow = 0; nRow < 6; ++nRow) {
		// Calculate this Y and set the next "last Y" value
		nY = nLastY;
		nLastY = nHeight - int (double (nRow + 1) * fBoxHeight);

		// Get the first "last X" value
		nLastX = nBorder;

		// Output each day in this row
		for (nCol = 0; nCol < 7; ++nCol) {
		    // Calculate this X and set the next "last X" value
		    nX = nLastX;
		    nLastX = int (double ((nCol + 1)) * fBoxWidth) + nBorder;

		    // Get the events for this day
		    pSchedulerDB->GetAllAppointments(nDate, mapEvent);

		    // Set up a map of times and meeting titles
		    vShortTime.clear();
		    vTime.clear();
		    vDescription.clear();

		    // Get the info on each meeting
		    for (iter = mapEvent.begin();
			 iter != mapEvent.end(); ++iter) {
			nTime = pSchedulerDB->GetStartTime(iter->second);
			pTm = localtime(&nTime);
			strKey =::FormatShortTime(nTime);
			strData =::FormatTime(nTime);
			nTime = pSchedulerDB->GetEndTime(iter->second);
			strKey += '-';
			strData += " - ";
			strKey +=::FormatShortTime(nTime);
			strData +=::FormatTime(nTime);
			vShortTime.push_back(strKey);
			vTime.push_back(strData);
			vDescription.push_back(pSchedulerDB->
					       GetDescription(iter->second));
		    }

		    // Now build this calendar box
		    pTm = localtime(&nDate);
		    printer.CalendarBox(nDate,
					pTm->tm_mday,
					(nMonth == pTm->tm_mon) ? 255 : 224,
					(nToday == nDate),
					nX,
					nLastY,
					nLastX - nX,
					nY - nLastY,
					vShortTime,
					vTime, vDescription, bOverflow);

		    // Special overflow processing
		    if (bOverflow == true) {
			// Save the date that overflowed
			vDate.push_back(nDate);

			// Add to the vectors of vectors
			vvTime.push_back(vTime);
			vvDescription.push_back(vDescription);
		    }
		    // Go to the next date
		    nDate =::AddDays(nDate, 1);
		}
	    }

	    // Add a page trailer
	    strTrailer =::FormatDate(nNow);
	    strTrailer += ' ';
	    strTrailer +=::FormatTime(nNow);
	    printer.PageTrailer(nBorder, nBorder);

	    // Finish any overflow processing for the calendar
	    printer.CalendarEnd(_("Scheduler Monthly"),
				184, vDate, vvTime, vvDescription);

	    // End the page
	    printer.EndPage();
	}

	// All done, close the printer
	printer.Close();

	// Reset the cursor
	PixilDT::GetApp()->GetMainWindow()->ResetCursor();
    }
}


//--------------------------------------------------------------//
// Resize the text in each browser if needed when resizeing     //
//--------------------------------------------------------------//
void
SchedulerMonthly::resize(int nX, int nY, int nWidth, int nHeight)
{
    int nOldWidth = w();

    // Then invoke the base class
    Fl_Group::resize(nX, nY, nWidth, nHeight);

    // Change the browsers only if needed
    if (nWidth != nOldWidth) {
	int i;
	int j;
	time_t nDate;
	struct tm *pTm;

	pTm = localtime(&m_nDate);
	nDate =::SubtractDays(m_nDate, pTm->tm_wday);

	// Refresh each browser
	for (i = 0; i < 6; ++i) {
	    for (j = 0; j < 7; ++j) {
		pTm = localtime(&nDate);
		BuildDate(nDate, i * 7 + j);
		nDate =::AddDays(nDate, 1);
	    }
	}
    }
}

--- NEW FILE: CategoryDB.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Base class for all Category database classes.                //
//--------------------------------------------------------------//
#include <FL/fl_ask.H>
#include "config.h"
#include "CategoryDB.h"
#include "CategoryDBDef.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Default categories if this is a new data base.               //
//--------------------------------------------------------------//
const char *
    CategoryDB::m_pszDefaultCategory[3] = {
    N_("Unfiled"),
    N_("Business"),
    N_("Personal")
};


//--------------------------------------------------------------//
// Field definitions used during construction.  (Kludge for     //
// different sized category names.)                             //
//--------------------------------------------------------------//
bool
    CategoryDB::m_bFieldInUse[4] = {
	false,
	false,
	false,
false };
field *
    CategoryDB::m_pStaticField[4];
fildes *
    CategoryDB::m_pStaticFildes[4];
int
    CategoryDB::m_nLastIndexUsed;


//--------------------------------------------------------------//
// Constructor (kludged due to varying lengths of category      //
// fields.                                                      //
//--------------------------------------------------------------//
CategoryDB::CategoryDB(const char *pszFileName, int nCategoryLength)
    :
NxDbAccess(pszFileName, m_pStaticFildes[m_nLastIndexUsed],
	   CreateFields(nCategoryLength))
{
    // Save the field definitions used by the construction process
    m_nIndex = m_nLastIndexUsed;

    // Init the database if needed
    Init();
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
CategoryDB::~CategoryDB()
{
    // Close this data base "early" so that the remainder of this
    // destructor can run without causing problems
    Close();

    // Free up the field definitions
    delete[]m_pStaticField[m_nIndex];
    delete[]m_pStaticFildes[m_nIndex];
    m_bFieldInUse[m_nIndex] = false;
}


//--------------------------------------------------------------//
// Called by the constructor to set up the fields for this data //
// base.                                                        //
//--------------------------------------------------------------//
field *
CategoryDB::CreateFields(int nCategoryLength)
{
    int i;

    // Find a static field definition not already in use
    for (i = 0; i < 4; ++i) {
	if (m_bFieldInUse[i] == false) {
	    break;
	}
    }

#ifdef DEBUG
    assert(i < 4);		// No open slots
#endif

    // Save for post constructor code
    m_nLastIndexUsed = i;

    m_bFieldInUse[i] = true;
    m_pStaticField[i] = new field[3];
    memcpy(m_pStaticField[i], catFields, 3 * sizeof(field));
    m_pStaticField[i][1].size = nCategoryLength;
    m_pStaticFildes[i] = new fildes;
    memcpy(m_pStaticFildes[i], &catFile, sizeof(fildes));
    m_pStaticFildes[i]->fieldp = m_pStaticField[i];
    return (m_pStaticField[i]);
}


//--------------------------------------------------------------//
// Create a menu for a category selection Fl_Choice widget.     //
//--------------------------------------------------------------//
Fl_Menu_Item *
CategoryDB::GetCategoryMenu(bool bIncludeAll)
{
    Fl_Menu_Item *pMenuItem;
    int i;
    int nMax = NumUndeletedRecs() + 1;

    // Create the menu
    pMenuItem = new Fl_Menu_Item[nMax + (bIncludeAll == true ? 1 : 0)];
    memset(pMenuItem, 0,
	   (nMax + (bIncludeAll == true ? 1 : 0)) * sizeof(Fl_Menu_Item));

    // Set up the all selection if needed
    if (bIncludeAll == true) {
	// Use strdup so that FreeTranslatedMenu will work correctly
	pMenuItem[0].text = strdup(_("All"));
    }
    // Add the categories to the menu
    Sort(CATID);
    for (i = 0; i < nMax - 1; ++i) {
	// Use strdup so that FreeTranslatedMenu will work correctly
	pMenuItem[i + (bIncludeAll == true ? 1 : 0)].text =
	    strdup(GetCategory(i).c_str());
    }
    return (pMenuItem);
}


//--------------------------------------------------------------//
// Create a menu for a category selection Fl_Choice widget      //
// using a preset font.                                         //
//--------------------------------------------------------------//
Fl_Menu_Item *
CategoryDB::GetCategoryMenuWithFont(bool bIncludeAll,
				    Fl_Font nFont, unsigned char nFontSize)
{
    Fl_Menu_Item *pMenuItem = GetCategoryMenu(bIncludeAll);
    int i;
    int nMax = NumUndeletedRecs() + (bIncludeAll ? 1 : 0);

    // Fix the font in the menu
    for (i = 0; i < nMax; ++i) {
	pMenuItem[i].labelfont(nFont);
	pMenuItem[i].labelsize(nFontSize);
    }
    return (pMenuItem);
}


//--------------------------------------------------------------//
// Initialize the database at open.                             //
//--------------------------------------------------------------//
void
CategoryDB::Init()
{
    // Init the data base if needed
    if (NumRecs() == 0) {
	int i;
	int nRow;

	for (i = 0; i < 3; ++i) {
	    nRow = Insert(i);
	    SetCategory(nRow, _(m_pszDefaultCategory[i]));
	}
	Save();
    }
}


//--------------------------------------------------------------//
// Insert a new row and set its key id.                         //
//--------------------------------------------------------------//
int
CategoryDB::Insert(int nID)
{
    int nRow = NxDbAccess::Insert();

    // Now set the key value requested by the caller
    if (nID < 0) {
	// Caller did not request one, set next highest
	SetHighKey(nRow, CATID);
    } else {
	// Caller requested a specific key
	SetColumn(nRow, CATID, nID);

	// Save this change so that an uninitialized key is
	// not left in the data base if the program fails
	Save();
    }

    return (nRow);
}


//--------------------------------------------------------------//
// Test a category name for duplicates.                         //
// pUserData starts out in the InputBox class as a void pointer //
// but is really the category ID of an existing category.  It   //
// is used here to prevent calling an unchanged name a          //
// duplicate when renaming categories.  Returns false if this   //
// is a duplicate category name.                                //
//--------------------------------------------------------------//
bool
CategoryDB::TestDuplicate(const char *pszString, void *pUserData)
{
    bool bReturn;
    int nThisCategory = reinterpret_cast < int >(pUserData);

    // Test if this is a duplicate string
    bReturn = NxDbAccess::TestDuplicate(pszString, nThisCategory, CAT, CATID);

    // Issue an error message if not valid
    if (bReturn == false) {
	fl_alert(_
		 ("This Category Name duplicates an existing category, please re-enter."));
    }

    return (bReturn);
}

--- NEW FILE: ListByDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// List By Dialog.                                              //
//--------------------------------------------------------------//
#ifndef LISTBYDLG_H_

#define LISTBYDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Window.H>
class ListByDlg:public Fl_Window
{
  public:ListByDlg(bool bSelection,
	      // Constructor
	      Fl_Widget * pParent);
    ~ListByDlg();		// Destructor
    int DoModal();		// Run the modal dialog
    inline bool GetSelection() const	// Get the selection, true = sort by last name
    {
	return (m_bSelection);
    }
  private:  bool m_bSelection;
    // The selection, true = sort by last name
    Fl_Button *m_pCancelButton;	// Cancel button
    Fl_Button *m_pHelpButton;	// Help button
    Fl_Button *m_pOKButton;	// OK button
    Fl_Check_Button *m_pRadioButton[2];	// The radio buttons
    static void OnHelpButton(Fl_Widget * pWidget,	// Process click on the Help button
			     void *pUserData);
};


#endif /*  */

--- NEW FILE: NoteEditor.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Note Editor widget                                           //
//--------------------------------------------------------------//
#ifndef NOTEEDITOR_H_

#define NOTEEDITOR_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <string>
#include <FL/Fl_Group.H>
#include <FL/Fl_Multiline_Input.H>
#include "Note.h"
#include "Toolbar.h"
using namespace std;
class NoteEditor:public Fl_Group
{
  public:NoteEditor(int nX,	// Constructor
	       int nY, int nWidth, int nHeight, bool bToolbar,
	       Note * pNote = NULL);
     ~NoteEditor();		// Destructor
    void Enable(bool bEnable);	// Enable/disable everything
    Note *GetNote();		// Get the note object
    void SetDestroyNote(bool bDestroyNote)	// Set to destroy the note at this object's destruction
    {
	m_bDestroyNote = bDestroyNote;
    }
    void SetNote(Note * pNote,	// Set the note to be displayed
		 bool bDestroy);
  private:bool m_bDestroyNote;
    // Whether this object should destroy the current note
    Fl_Multiline_Input *m_pInput;	// The note input area
    Note *m_pNote;		// The actual note
    Toolbar *m_pToolbar;	// Toolbar
    static const ToolbarItem m_ToolbarItem[];	// Toolbar definition
    static void EditCopy(Fl_Widget * pWidget,	// Copy from toolbar
			 void *pUserData);
    static void EditCut(Fl_Widget * pWidget,	// Cut from toolbar
			void *pUserData);
    static void EditPaste(Fl_Widget * pWidget,	// Paste from toolbar
			  void *pUserData);
    static void EditUndo(Fl_Widget * pWidget,	// Undo from toolbar
			 void *pUserData);
};


#endif /*  */

--- NEW FILE: SchedulerRepeatData.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for processing Scheduler data base repeat settings for //
// a row.                                                       //
//--------------------------------------------------------------//
#ifndef SCHEDULERREPEATDATA_H_

#define SCHEDULERREPEATDATA_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

//--------------------------------------------------------------//
// Class to perform all manipulations on repetition settings    //
// for an event.  Vurrent field usage is:                       //
//                                                              //
// Repeat Flag 1 - type of repetition for the event, None,      //
//        Daily, Weekly, Monthly or Yearly.                     //
// Repeat Flag 2 - number of units between repetitions.         //
//--------------------------------------------------------------//
class SchedulerRepeatData
{
  public:SchedulerRepeatData(int nStartTime,
			// Constructor
			int nEndTime, int nRepeatFlag1 =
			0, int nRepeatFlag2 = 0, int nRepeatFlag3 =
			0, int nRepeatWeekMonth = 0);
      SchedulerRepeatData(const SchedulerRepeatData & Other);	// Copy constructor
    inline bool operator==(const SchedulerRepeatData & Other) const	// Comparison operator
    {
	return (m_nRepeatFlag1 == Other.m_nRepeatFlag1
		&& m_nRepeatFlag2 == Other.m_nRepeatFlag2
		&& m_nRepeatFlag3 == Other.m_nRepeatFlag3
		&& m_nRepeatWeekMonth == Other.m_nRepeatWeekMonth
		&& m_nEndTime == Other.m_nEndTime
		&& m_nStartTime == Other.m_nStartTime);
    }
    inline time_t GetEndDate() const	// Get the end date for this event
    {
	return (m_nRepeatFlag3);
    }
    inline bool GetRepeatByDow(int nDow) const	// Get whether this event repeats on this day of the week
    {
	return (((m_nRepeatWeekMonth >> nDow) & 0x01) == 0x01 ? true : false);
    }
    time_t GetRepeatDate(int nIndex) const;	// Get a date on which this event will repeat
    inline int GetRepeatEvery() const	// Get the number or days/weeks/months/years between repetitions
    {
	return (m_nRepeatFlag2 >=
		1 ? (m_nRepeatFlag2 <= 999 ? m_nRepeatFlag2 : 999) : 1);
    }
    inline int GetRepeatFlag1() const	// Get repeat flag 1
    {
	return (m_nRepeatFlag1);
    }
    inline int GetRepeatFlag2() const	// Get repeat flag 2
    {
	return (m_nRepeatFlag2);
    }
    inline int GetRepeatFlag3() const	// Get repeat flag 3
    {
	return (m_nRepeatFlag3);
    }
    int GetRepeatIndex() const;	// Get the repeat type as an index 0 through 4
    inline bool GetRepeatMonthByDay() const	// Get if the repeat monthly by week and day of week is true
    {
	return ((m_nRepeatWeekMonth & REPEAT_MONTH_DAY) != 0);
    }
    inline int GetRepeatType()	// Get the repeat type
    {
	return (m_nRepeatFlag1);
    }
    string GetRepeatTypeString() const;	// Get the repeat type as a string
    inline int GetRepeatWeekMonth() const	// Get weekly/monthly repeat flag
    {
	return (m_nRepeatWeekMonth);
    }
    void GetStartEnd(int &nStartSlot,	// Get the start and end time slots for drawing this appointment
		     int &nEndSlot, int nSlotSize) const;
    time_t GetStartTime() const	// Get the start time for this event
    {
	return (m_nStartTime);
    }
    void GetYearlyEvents(bool * pbEvent,	// Get indications as to which days of a year have scheduled events
			 time_t nYear) const;
    bool IsOnDay(time_t nTime) const;	// Does this event occur on a particular date
    bool IsWeekDaySelected(int nDow) const;	// Get whether a weekday has been selected or not
    void SetDailyRepetition(int nEvery,	// Set that the event will repeat on a daily basis
			    time_t nEndDate);
    void SetMonthlyRepetition(int nEvery,	// Set that the event will repeat on a monthly basis
			      int nRepeatType, time_t nEndDate);
    void SetNoRepetition();	// Set that the event will not repeat
    void SetStartDate(time_t nDate);	// Change the start date
    void SetWeeklyRepetition(int nEvery,	// Set that the event will repeat on a weekly basis
			     int nDow0, int nDow1, int nDow2, int nDow3,
			     int nDow4, int nDow5, int nDow6,
			     time_t nEndDate);
    void SetYearlyRepetition(int nEvery,	// Set that the event will repeat on a yearly basis
			     time_t nEndDate);
  private:int m_nRepeatFlag1;
    // First repeat flag
    int m_nRepeatFlag2;		// Second repeat flag
    int m_nRepeatFlag3;		// Third repeat flag
    int m_nRepeatWeekMonth;	// Weekly/Monthly repeat flags
    time_t m_nEndTime;		// End date/time of the event
    time_t m_nStartTime;	// Start date/time of the event
};


#endif /*  */

--- NEW FILE: SchedulerRepeatData.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for processing Scheduler data base repeat settings for //
// a row.                                                       //
//--------------------------------------------------------------//
#include <ctime>
#include "SchedulerDB.h"
#include "TimeFunc.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Constructor                                                  //
//--------------------------------------------------------------//
SchedulerRepeatData::SchedulerRepeatData(int nStartTime,
					 int nEndTime,
					 int nRepeatFlag1,
					 int nRepeatFlag2,
					 int nRepeatFlag3,
					 int nRepeatWeekMonth)
{
    // Save all of these values
    m_nStartTime = nStartTime;
    m_nEndTime = nEndTime;
    m_nRepeatFlag1 = nRepeatFlag1;
    m_nRepeatFlag2 = nRepeatFlag2;
    m_nRepeatFlag3 = nRepeatFlag3;
    m_nRepeatWeekMonth = nRepeatWeekMonth;
}


//--------------------------------------------------------------//
// Copy constructor                                             //
//--------------------------------------------------------------//
SchedulerRepeatData::SchedulerRepeatData(const SchedulerRepeatData & Other)
{
    m_nStartTime = Other.m_nStartTime;
    m_nEndTime = Other.m_nEndTime;
    m_nRepeatFlag1 = Other.m_nRepeatFlag1;
    m_nRepeatFlag2 = Other.m_nRepeatFlag2;
    m_nRepeatFlag3 = Other.m_nRepeatFlag3;
    m_nRepeatWeekMonth = Other.m_nRepeatWeekMonth;
}


//--------------------------------------------------------------//
// Get a repeat date given an index.  The returned time will be //
// normalized to midnight.                                      //
//--------------------------------------------------------------//
time_t
SchedulerRepeatData::GetRepeatDate(int nIndex) const
{
    int i;
    int nCount;
    int nDays;
    int nDow;
    int nDow2;
    int nIndex2;
    int nMonth;
    int nOffset = 0;
    int nRepeat;
    int nWeek;
    int nWeekFlag;
    time_t nReturn;
    struct tm *pTm;

    switch (m_nRepeatFlag1) {
    case REPEAT_NONE:
	if (nIndex == 0) {
	    // Only happens on this day
	    nReturn =::NormalizeDate(m_nStartTime);
	} else {
	    // Does not repeat
	    nReturn = 0;
	}
	break;

    case REPEAT_DAILY:
	nReturn =::AddDays(::NormalizeDate(m_nStartTime),
			   nIndex * GetRepeatEvery());
	if (GetEndDate() >= 24 * 60 * 60
	    && nReturn >::NormalizeDate(GetEndDate())) {
	    // Too far into the future
	    nReturn = 0;
	}
	break;

    case REPEAT_WEEKLY:
	// Get the first day for this event
	nDow = GetDow(m_nStartTime);
	nReturn =::NormalizeDate(m_nStartTime);
	for (i = nDow; i < 7; ++i) {
	    if (((0x01 << i) & m_nRepeatWeekMonth) != 0) {
		break;
	    } else {
		nReturn =::AddDays(nReturn, 1);
	    }
	}
	if (i >= 7) {
	    // Try again into the next week
	    for (i = 0; i < nDow; ++i) {
		if (((0x01 << i) & m_nRepeatWeekMonth) != 0) {
		    break;
		} else {
		    nReturn =::AddDays(nReturn, 1);
		}
	    }
#ifdef DEBUG
	    assert(i < nDow);	// Must have found a day
#endif
	}
	// Reset the index if this is for a weekly event
	pTm = localtime(&nReturn);
	switch (pTm->tm_wday) {
	case 6:		// On a Saturday
	    nOffset +=
		((m_nRepeatWeekMonth & REPEAT_WEEK_FRIDAY) != 0 ? 1 : 0);
	    // Fall through

	case 5:		// On a Friday
	    nOffset +=
		((m_nRepeatWeekMonth & REPEAT_WEEK_THURSDAY) != 0 ? 1 : 0);
	    // Fall through

	case 4:		// On a Thursday
	    nOffset +=
		((m_nRepeatWeekMonth & REPEAT_WEEK_WEDNESDAY) != 0 ? 1 : 0);
	    // Fall through

	case 3:		// On a Wednesday
	    nOffset +=
		((m_nRepeatWeekMonth & REPEAT_WEEK_TUESDAY) != 0 ? 1 : 0);
	    // Fall through

	case 2:		// On a Tuesday
	    nOffset +=
		((m_nRepeatWeekMonth & REPEAT_WEEK_MONDAY) != 0 ? 1 : 0);
	    // Fall through

	case 1:		// On a Monday
	    nOffset +=
		((m_nRepeatWeekMonth & REPEAT_WEEK_SUNDAY) != 0 ? 1 : 0);
	}

	// Get the number of times per week
	nDow = ((m_nRepeatWeekMonth & REPEAT_WEEK_SUNDAY) != 0 ? 1 : 0)
	    + ((m_nRepeatWeekMonth & REPEAT_WEEK_MONDAY) != 0 ? 1 : 0)
	    + ((m_nRepeatWeekMonth & REPEAT_WEEK_TUESDAY) != 0 ? 1 : 0)
	    + ((m_nRepeatWeekMonth & REPEAT_WEEK_WEDNESDAY) != 0 ? 1 : 0)
	    + ((m_nRepeatWeekMonth & REPEAT_WEEK_THURSDAY) != 0 ? 1 : 0)
	    + ((m_nRepeatWeekMonth & REPEAT_WEEK_FRIDAY) != 0 ? 1 : 0)
	    + ((m_nRepeatWeekMonth & REPEAT_WEEK_SATURDAY) != 0 ? 1 : 0);

	// Determine how many full weeks into the repetition
	nIndex2 = nIndex + nOffset;
	nIndex2 /= nDow;

	// Get the date of the Saturday prior to the Sunday of the week
	// in which this repetition will occur
	nReturn =::AddDays(nReturn,
			   7 * nIndex2 * GetRepeatEvery() - GetDow(nReturn) -
			   1);
	pTm = localtime(&nReturn);
	nRepeat = ((nIndex + nOffset) % nDow);
	nCount = 0;
	nWeekFlag = (m_nRepeatWeekMonth & REPEAT_WEEK_FLAGS);

	// Now offset this for the number of repetitions within the week
	while (nCount <= nRepeat) {
#ifdef DEBUG
	    assert(nWeekFlag != 0);	// Too many bits are off
#endif
	    while ((nWeekFlag & 0x01) == 0) {
		nReturn =::AddDays(nReturn, 1);
		nWeekFlag >>= 1;
	    }

	    // Use this day
	    nReturn =::AddDays(nReturn, 1);
	    nWeekFlag >>= 1;
	    ++nCount;
	}

	// Say that there isn't one if too far into the future
	if (GetEndDate() >= 24 * 60 * 60
	    && nReturn >::NormalizeDate(GetEndDate())) {
	    // Too far into the future
	    nReturn = 0;
	}
	break;

    case REPEAT_MONTHLY:
	switch (m_nRepeatWeekMonth) {
	case REPEAT_MONTH_DATE:	// Repeats on the day day of the month
	    // Go to the requested month
	    pTm = localtime(&m_nStartTime);
	    pTm->tm_isdst = -1;
	    pTm->tm_sec = 0;
	    pTm->tm_min = 0;
	    pTm->tm_hour = 0;
	    pTm->tm_mon += nIndex * GetRepeatEvery();
	    pTm->tm_year += pTm->tm_mon / 12;
	    pTm->tm_mon %= 12;
	    if (pTm->tm_mday > 30 && (pTm->tm_mon == 3	// April
				      || pTm->tm_mon == 5	// June
				      || pTm->tm_mon == 8	// September
				      || pTm->tm_mon == 10))	// November
	    {
		pTm->tm_mday = 30;
	    } else if (pTm->tm_mday > 28 && pTm->tm_mon == 1)	// February
	    {
		if ((pTm->tm_year % 4) == 0) {
		    if (pTm->tm_mday > 29) {
			pTm->tm_mday = 29;
		    }
		} else {
		    pTm->tm_mday = 28;
		}
	    }
	    nReturn = mktime(pTm);
	    break;

	case REPEAT_MONTH_DAY:	// Repeats on the week and weekday of the month
	    // Get the week and day of week
	    nWeek = GetMonthWeek(m_nStartTime);
	    nDow = GetDow(m_nStartTime);

	    // Go to the first of the requested month
	    pTm = localtime(&m_nStartTime);
	    pTm->tm_isdst = -1;
	    pTm->tm_sec = 0;
	    pTm->tm_min = 0;
	    pTm->tm_hour = 0;
	    pTm->tm_mday = 1;
	    pTm->tm_mon += nIndex * GetRepeatEvery();
	    pTm->tm_year += pTm->tm_mon / 12;
	    pTm->tm_mon %= 12;

	    // Save the month for later
	    nMonth = pTm->tm_mon;

	    // Get the first of the new month
	    nReturn = mktime(pTm);

	    // Get the number of days into the month
	    nDow2 =::GetDow(nReturn);
	    nDays = 7 * nWeek + nDow - nDow2 + (nDow < nDow2 ? 7 : 0);

	    // Get the first try at the date
	    nReturn =::AddDays(nReturn, nDays);

	    // Fix if past the end of the selected month
	    pTm = localtime(&nReturn);
	    while (pTm->tm_mon != nMonth) {
		nReturn =::SubtractDays(nReturn, 1);
		pTm = localtime(&nReturn);
	    }
	    break;

	default:
#ifdef DEBUG
	    assert(false);	// Bad monthly repeat flag
#endif
	    nReturn = 0;	// Say that it does not repeat here
	}

	// Say that there isn't one if too far into the future
	if (GetEndDate() >= 24 * 60 * 60
	    && nReturn >::NormalizeDate(GetEndDate())) {
	    // Too far into the future
	    nReturn = 0;
	}
	break;

    case REPEAT_YEARLY:
	// Go to the requested year
	pTm = localtime(&m_nStartTime);
	pTm->tm_isdst = -1;
	pTm->tm_sec = 0;
	pTm->tm_min = 0;
	pTm->tm_hour = 0;
	pTm->tm_year += nIndex * GetRepeatEvery();
	if (pTm->tm_mday > 28 && pTm->tm_mon == 1	// February
	    && (pTm->tm_year % 4) != 0) {
	    pTm->tm_mday = 28;
	}

	nReturn = mktime(pTm);

	// Say that there isn't one if too far into the future
	if (GetEndDate() >= 24 * 60 * 60
	    && nReturn >::NormalizeDate(GetEndDate())) {
	    // Too far into the future
	    nReturn = 0;
	}
	break;

    default:
#ifdef DEBUG
	assert(false);		// Invalid repetition type
#endif
	nReturn = 0;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Get the repeat type as a numeric index 0 through 4.          //
//--------------------------------------------------------------//
int
SchedulerRepeatData::GetRepeatIndex() const
{
    static int nRepeatType[5] =
	{ REPEAT_NONE, REPEAT_DAILY, REPEAT_WEEKLY, REPEAT_MONTHLY,
REPEAT_YEARLY };
    int nIndex;

    for (nIndex = 0; nIndex < 5; ++nIndex) {
	if (nRepeatType[nIndex] == m_nRepeatFlag1) {
	    break;
	}
    }

    if (nIndex >= 5) {
#ifdef DEBUG
	assert(false);		// Bad repeat flag 1
#endif
	nIndex = 0;
    }

    return (nIndex);
}


//--------------------------------------------------------------//
// Get the start and end slots for drawing this appointment.    //
//--------------------------------------------------------------//
void
SchedulerRepeatData::GetStartEnd(int &nStartSlot,
				 int &nEndSlot, int nSlotSize) const
{
    struct tm *pTm = localtime(&m_nStartTime);

    nStartSlot =
	(pTm->tm_hour * 60 * 60 + pTm->tm_min * 60 + pTm->tm_sec) / nSlotSize;
    pTm = localtime(&m_nEndTime);
    nEndSlot =
	(pTm->tm_hour * 60 * 60 + pTm->tm_min * 60 + pTm->tm_sec -
	 1) / nSlotSize;
    if (nEndSlot < nStartSlot) {
	nEndSlot = nStartSlot;
    }
}


//--------------------------------------------------------------//
// Get the repeat type, not inline because of recursive header  //
// includes.                                                    //
//--------------------------------------------------------------//
string
SchedulerRepeatData::GetRepeatTypeString() const
{
    return (SchedulerDB::GetRepeatTypeString(m_nRepeatFlag1));
}


//--------------------------------------------------------------//
// Mark the days of the year that have scheduled events.        //
// Assumes that pbEvent is an array of at least 366 bools.      //
//--------------------------------------------------------------//
void
SchedulerRepeatData::GetYearlyEvents(bool * pbEvent, time_t nTimeYear) const
{
    bool bDone = false;
    int i;
    int nYear;
    time_t nTime;
    struct tm *pTm;

    // Get the year
    pTm = localtime(&nTimeYear);
    nYear = pTm->tm_year;

    // Is the start date after the end of this year ?
    pTm = localtime(&m_nStartTime);
    if (pTm->tm_year > nYear) {
	bDone = true;
    }
    // Does this event end before the start of this year
    if (bDone == false) {
	nTime = GetEndDate();
	if (nTime >= 24 * 60 * 60) {
	    pTm = localtime(&nTime);
	    if (pTm->tm_year < nYear) {
		bDone = true;
	    }
	}
    }
    // Now test each repetition of the event against this year
    if (bDone == false) {
	i = 0;
	do {
	    // Get the next repeat date
	    nTime = GetRepeatDate(i);

	    // Is the event still repeating
	    if (nTime >= 24 * 60 * 60) {
		// Test the year of the event
		pTm = localtime(&nTime);
		if (pTm->tm_year == nYear) {
		    // Mark this day of year as having an event
		    pbEvent[pTm->tm_yday] = true;
		} else if (pTm->tm_year > nYear) {
		    // Past the year in question, quit
		    break;
		}
	    }
	    // Increment the repeat index
	    ++i;
	} while (nTime >= 24 * 60 * 60);
    }
}


//--------------------------------------------------------------//
// Test if event will occur on a particular day.                //
//--------------------------------------------------------------//
bool
SchedulerRepeatData::IsOnDay(time_t nTime) const
{
    bool bReturn = false;
    int nBetween;

#ifdef DEBUG
    assert(nTime ==::NormalizeDate(nTime));	// Must be a normalized date
#endif

    if (nTime >=::NormalizeDate(m_nStartTime)
	&& (GetEndDate() < 24 * 60 * 60
	    || nTime <=::NormalizeDate(GetEndDate()))) {
	switch (m_nRepeatFlag1) {
	case REPEAT_NONE:	// Does not repeat
	    if (nTime ==::NormalizeDate(m_nStartTime)) {
		bReturn = true;
	    }
	    break;

	case REPEAT_DAILY:	// Repeats on a daily basis
	    nBetween = DaysBetween(nTime,::NormalizeDate(m_nStartTime));
	    if ((nBetween % GetRepeatEvery()) == 0) {
		// This is on a correct day
		bReturn = true;
	    }
	    break;

	case REPEAT_WEEKLY:
	    if (IsWeekDaySelected(GetDow(nTime)) == true) {
		// On the correct weekday, get the number of weeks between the two dates
		nBetween = WeeksBetween(nTime,::NormalizeDate(m_nStartTime));

		// Is it on a good week
		if ((nBetween % GetRepeatEvery()) == 0) {
		    // This is on a correct week
		    bReturn = true;
		}
	    }
	    break;

	case REPEAT_MONTHLY:
	    // Determine how to repeat this event
	    switch (GetRepeatWeekMonth()) {
	    case REPEAT_MONTH_DAY:	// Repeats on the week and weekday of the month
		// Test if the target date is on the same day-of-week
		if (GetDow(m_nStartTime) == GetDow(nTime)) {
		    // Test if the target date is in the same week of the month
		    if (GetMonthWeek(m_nStartTime) == GetMonthWeek(nTime)) {
			// Now test for the "repeats" every setting
			nBetween = MonthsBetween(nTime, m_nStartTime);
			if ((nBetween % GetRepeatEvery()) == 0) {
			    // This is on a correct month
			    bReturn = true;
			}
		    }
		}
		break;

	    case REPEAT_MONTH_DATE:	// Repeats on the same day of the month
		if (IsDayOfMonth(nTime, m_nStartTime) == true) {
		    // Now test for the "repeats" every setting
		    nBetween = MonthsBetween(nTime, m_nStartTime);
		    if ((nBetween % GetRepeatEvery()) == 0) {
			// This is on a correct month
			bReturn = true;
		    }
		}
		break;

	    default:
#ifdef DEBUG
		assert(false);	// Incorrect type for month repeat
#endif
		;
	    }
	    break;

	case REPEAT_YEARLY:
	    // Is this on the correct month and day-of-month
	    if (IsDayOfYear(nTime, m_nStartTime) == true) {
		// Now test for the "repeats every setting
		nBetween = YearsBetween(nTime, m_nStartTime);
		if ((nBetween % GetRepeatEvery()) == 0) {
		    // This is on a correct year
		    bReturn = true;
		}
	    }
	    break;

	default:
#ifdef DEBUG
	    assert(false);	// Incorrect repeat flag 1
#endif
	    ;
	}
    }
    return (bReturn);
}


//--------------------------------------------------------------//
// Test if a particular weekday has been selected or not.       //
// This test makes useof the fact that the Sunday through       //
// Saturday bits can be represented by a simple bit shift.      //
//--------------------------------------------------------------//
bool
SchedulerRepeatData::IsWeekDaySelected(int nDow) const
{
#ifdef DEBUG
    assert(nDow >= 0 && nDow < 7);
#endif

    return (((0x01 << (nDow)) & m_nRepeatWeekMonth) != 0);
}


//--------------------------------------------------------------//
// Set that the event repeats on a daily basis.  The nEvery     //
// argument is the number of days between repetitions and the   //
// nEndDate argument is the end day, the event will not repeat  //
// after this date.  If nEndDate is less than the event start   //
// date then this function will assume that there is no end     //
// date (no repetitions).                                       //
//--------------------------------------------------------------//
void
SchedulerRepeatData::SetDailyRepetition(int nEvery, time_t nEndDate)
{
    // Set the simple settings
    m_nRepeatFlag1 = REPEAT_DAILY;
    m_nRepeatFlag2 = (nEvery < 0 || nEvery > 999 ? 999 : nEvery);
    m_nRepeatWeekMonth = 0;

    // Set the end date
    m_nRepeatFlag3 =
	(nEndDate >= 24 * 60 * 60 ?::NormalizeDate(nEndDate) : 0);
}


//--------------------------------------------------------------//
// Set that the event repeats on a monthly basis.  The nEvery   //
// argument is the number of months between repetitions and the //
// nEndDate argument is the end day, the event will not repeat  //
// after this date.  If nEndDate is less than the event start   //
// date then this function will assume that there is no end     //
// date (no repetitions).  The nRepeatType argument indicates   //
// how the event repeats, a zero indicates that the date        //
// repeats on a particular day of the month while any other     //
// value indicates that the event repeats on the same day of    //
// week in the same week of the month as the original event.    //
//--------------------------------------------------------------//
void
SchedulerRepeatData::SetMonthlyRepetition(int nEvery,
					  int nRepeatType, time_t nEndDate)
{
    // Set the simple settings
    m_nRepeatFlag1 = REPEAT_MONTHLY;
    m_nRepeatFlag2 = (nEvery < 0 || nEvery > 999 ? 999 : nEvery);

    // Set the monthly repeat flag
    m_nRepeatWeekMonth =
	(nRepeatType == 0 ? REPEAT_MONTH_DATE : REPEAT_MONTH_DAY);

    // Set the end date
    m_nRepeatFlag3 =
	(nEndDate >= 24 * 60 * 60 ?::NormalizeDate(nEndDate) : 0);
}


//--------------------------------------------------------------//
// Set that the event does not repeat.                          //
//--------------------------------------------------------------//
void
SchedulerRepeatData::SetNoRepetition()
{
    m_nRepeatFlag1 = REPEAT_NONE;
    m_nRepeatFlag2 = 0;
    m_nRepeatFlag3 = 0;
    m_nRepeatWeekMonth = 0;
}


//--------------------------------------------------------------//
// Change the date for this repeating event.                    //
//--------------------------------------------------------------//
void
SchedulerRepeatData::SetStartDate(time_t nDate)
{
    // Set the starting time
    m_nStartTime = nDate + (m_nStartTime -::NormalizeDate(m_nStartTime));

    // Set the ending time
    m_nEndTime = nDate + (m_nEndTime -::NormalizeDate(m_nEndTime));
}


//--------------------------------------------------------------//
// Set that the event repeats on a weekly basis.  The nEvery    //
// argument is the number of weeks between repetitions and the  //
// nEndDate argument is the end day, the event will not repeat  //
// after this date.  If nEndDate is less than the event start   //
// date then this function will assume that there is no end     //
// date (no repetitions).  The number of repetitions represents //
// the number of full weeks, when an event occurs on more than  //
// one weekday and also repeats, the repetition includes all    //
// weekdays.                                                    //
//--------------------------------------------------------------//
void
SchedulerRepeatData::SetWeeklyRepetition(int nEvery,
					 int nDow0,
					 int nDow1,
					 int nDow2,
					 int nDow3,
					 int nDow4,
					 int nDow5,
					 int nDow6, time_t nEndDate)
{
    // Set the simple settings
    m_nRepeatFlag1 = REPEAT_WEEKLY;
    m_nRepeatFlag2 = (nEvery < 0 || nEvery > 999 ? 999 : nEvery);

#ifdef DEBUG
    assert(nDow0 != 0 || nDow1 != 0 || nDow2 != 0 || nDow3 != 0 || nDow4 != 0
	   || nDow5 != 0 || nDow6 != 0);
#endif

    // Set the days of the week on which to repeat the event
    m_nRepeatWeekMonth = (nDow0 != 0 ? REPEAT_WEEK_SUNDAY : 0)
	+ (nDow1 != 0 ? REPEAT_WEEK_MONDAY : 0)
	+ (nDow2 != 0 ? REPEAT_WEEK_TUESDAY : 0)
	+ (nDow3 != 0 ? REPEAT_WEEK_WEDNESDAY : 0)
	+ (nDow4 != 0 ? REPEAT_WEEK_THURSDAY : 0)
	+ (nDow5 != 0 ? REPEAT_WEEK_FRIDAY : 0)
	+ (nDow6 != 0 ? REPEAT_WEEK_SATURDAY : 0);

    // Set the end date
    m_nRepeatFlag3 =
	(nEndDate >= 24 * 60 * 60 ?::NormalizeDate(nEndDate) : 0);
}


//--------------------------------------------------------------//
// Set that the event repeats on a yearly basis.  The nEvery    //
// argument is the number of years between repetitions and the  //
// nEndDate argument is the end day, the event will not repeat  //
// after this date.  If nEndDate is less than the event start   //
// date then this function will assume that there is no end     //
// date (no repetitions).                                       //
//--------------------------------------------------------------//
void
SchedulerRepeatData::SetYearlyRepetition(int nEvery, time_t nEndDate)
{
    // Set the simple settings
    m_nRepeatFlag1 = REPEAT_YEARLY;
    m_nRepeatFlag2 = (nEvery < 0 || nEvery > 999 ? 999 : nEvery);
    m_nRepeatWeekMonth = 0;

    // Set the end date
    m_nRepeatFlag3 =
	(nEndDate >= 24 * 60 * 60 ?::NormalizeDate(nEndDate) : 0);
}

--- NEW FILE: CategoryDeleteDlg.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Category Delete dialog.                                      //
//--------------------------------------------------------------//
#ifndef CATEGORYDELETEDLG_H_

#define CATEGORYDELETEDLG_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <FL/Fl_Window.H>
class CategoryDeleteDlg:public Fl_Window
{
  public:CategoryDeleteDlg();
    // Constructor
    ~CategoryDeleteDlg();	// Destructor
};


#endif /*  */

--- NEW FILE: SchedulerMonthly.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Scheduler Monthly tab page                                   //
//--------------------------------------------------------------//
#ifndef SCHEDULERMONTHLY_H_

#define SCHEDULERMONTHLY_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <ctime>
#include <map>
#include <string>
#include <FL/Fl_Box.H>
#include <FL/Fl_Browser.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Group.H>
#include "Messages.h"
using namespace std;
class SchedulerMonthly:public Fl_Group
{
  public:SchedulerMonthly(int nX,
		     // Constructor
		     int nY, int nWidth, int nHeight);
     ~SchedulerMonthly();	// Destructor
    int handle(int nEvent);	// Handle events for this widget
    int Message(PixilDTMessage nMessage,	// Message from the parent widget
		int nInfo);
    void Print();		// Print this data
    void resize(int nX,		// From Fl_Widget/Fl_Group - virtual resize method
		int nY, int nWidth, int nHeight);
  private:  Fl_Box * m_pDate;
    // Date banner at the top of the page
    Fl_Box *m_pDow[7];		// Day of week names
    Fl_Browser *m_pDay[6][7];	// Day boxes for the calendar
    Fl_Button *m_pGoToButton;	// Goto button
    Fl_Button *m_pLeftButton;	// Left arrow button
    Fl_Button *m_pRightButton;	// Right arrow button
    Fl_Button *m_pTodayButton;	// Today button
    Fl_Pixmap *m_pLeftPixmap;	// Left arrow pixmap
    Fl_Pixmap *m_pRightPixmap;	// Right arrow pixmap
    time_t m_nDate;		// Date currently being displayed
    string m_strDateLabel;	// Banner label at the top of the page
    string m_strDow[7];		// Day-of-week titles
      multimap < int, int >m_pmEvent[42];	// Events for each day, the key is the 1440*(start time in minutes)+end time in minutes
    void BuildDate(time_t nStartDate,	// Create a browser's information for a date
		   int nDayNo);
    void DisplayDay(time_t nDate);	// Display the month for a particular day
    static void OnGotoButton(Fl_Widget * pWidget,	// Process a click on the goto buttton
			     void *pUserData);
    static void OnLeftButton(Fl_Widget * pWidget,	// Process a click on the left buttton
			     void *pUserData);
    static void OnRightButton(Fl_Widget * pWidget,	// Process a click on the right buttton
			      void *pUserData);
    static void OnTodayButton(Fl_Widget * pWidget,	// Process a click on the today buttton
			      void *pUserData);
  public:void Refresh()
    {
	DisplayDay(m_nDate);
    }
};


#endif /*  */

--- NEW FILE: NoteDetails.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Class for the Note Details.                                  //
//--------------------------------------------------------------//
#ifndef NOTEDETAILS_H_

#define NOTEDETAILS_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include "config.h"
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Input.H>
#include "Messages.h"
#include "NoteEditor.h"
class NoteDetails:public Fl_Group
{
  public:NoteDetails(int nX,	// Constructor
		int nY, int nWidth, int nHeight);
     ~NoteDetails();		// Destructor
    void DisplayRow(int nRow,	// Display a Note
		    int nCategory);
    void Enable(bool bEnable);	// Enable or disable all input in the details
    int Message(PixilDTMessage nMessage,	// Process a message from the parent widget
		int nInfo);
    int SaveChanges(bool bAsk);	// Save any changes to disk
  private:  Fl_Box * m_pCategoryPrompt;
    // The prompt for the category choice
    Fl_Box *m_pTitlePrompt;	// The prompt for the description
    Fl_Button *m_pApplyButton;	// The Apply button
    Fl_Choice *m_pCategoryChoice;	// The category choice
    Fl_Input *m_pTitle;		// The note description
    Fl_Menu_Item *m_pCategoryMenu;	// Category choice menu
    int m_nIndex;		// The note index being displayed
    NoteEditor *m_pNoteEditor;	// The note text
    static void OnApply(Fl_Widget * pWidget,	// Process an apply button click
			void *pUserData);
};


#endif /*  */

--- NEW FILE: NxDb0006.txt ---
notcat
#1 0,"Unfiled"
#2 1,"Business"
#3 2,"Personal"

--- NEW FILE: ToDoList.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// Center of the window for the ToDo List display               //
//--------------------------------------------------------------//
#include "config.h"
#include <cassert>
#include <FL/fl_ask.H>
#include "Dialog.h"
#include "FLTKUtil.h"
#include "Images.h"
#include "Options.h"
#include "PixilDT.h"
#include "ToDoList.h"
#include "ToDoListCategoryDB.h"
#include "ToDoListShowDlg.h"

#include "VCMemoryLeak.h"


//--------------------------------------------------------------//
// Default constructor                                          //
//--------------------------------------------------------------//
ToDoList::ToDoList(Fl_Widget * pParent)
:  Fl_Group(pParent->x(), pParent->y(), pParent->w(), pParent->h())
{
    // Initialize these
    m_bUndoCut = false;
    m_bUndoPaste = false;

    // Reset the default color
    color(FL_GRAY);

    // Set up the details display, must be first as the list makes use of it during construction.
    m_pToDoListDetails =
	new ToDoListDetails(x() + w() - DETAILS_WIDTH - DLG_BORDER,
			    y() + DLG_BORDER, DETAILS_WIDTH,
			    h() - 2 * DLG_BORDER);
    m_pToDoListDetails->Enable(false);

    // Set up the title
    m_pTitle = new Fl_Box(x() + DLG_BORDER,
			  y() + DLG_BORDER,
			  PAGE_LABEL_WIDTH, DLG_BUTTON_HEIGHT);
    m_pTitle->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_WRAP);
    m_pTitle->label(_("To Do List"));
    m_pTitle->box(FL_DOWN_BOX);
    m_pTitle->labelfont(FL_HELVETICA_BOLD);

    m_pCategory =
	new Fl_Choice(x() + w() - DETAILS_WIDTH - 2 * DLG_BORDER -
		      CATEGORY_CHOICE_WIDTH, y() + DLG_BORDER,
		      CATEGORY_CHOICE_WIDTH, DLG_BUTTON_HEIGHT);
    m_pCategoryMenu =
	ToDoListCategoryDB::GetToDoListCategoryDB()->GetCategoryMenu(true);
    m_pCategory->menu(m_pCategoryMenu);
    m_pCategory->callback(CategorySelected);

    // Set up the list
    m_pToDoListList = new ToDoListList(x() + DLG_BORDER, y() + 2 * DLG_BORDER + DLG_BUTTON_HEIGHT, w() - DETAILS_WIDTH - 3 * DLG_BORDER, h() - 4 * DLG_BORDER - 2 * DLG_BUTTON_HEIGHT, false);	// Not a small list
    m_pToDoListList->color(FL_WHITE);

    // Set up the buttons
    m_pShowButton =
	new Fl_Button(x() + w() - 2 * (DLG_BUTTON_WIDTH + DLG_BORDER) -
		      DETAILS_WIDTH - DLG_BORDER,
		      y() + h() - (DLG_BORDER + DLG_BUTTON_HEIGHT),
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, _("Sh&ow..."));
    m_pShowButton->callback(ShowButton);
    m_pNewButton =
	new Fl_Button(x() + w() - (DLG_BUTTON_WIDTH + DLG_BORDER) -
		      DETAILS_WIDTH - DLG_BORDER,
		      y() + h() - (DLG_BORDER + DLG_BUTTON_HEIGHT),
		      DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT, _("&New"));
    m_pNewButton->callback(NewButton);
    end();

    // Set that the list area is resizable
    resizable(m_pToDoListList);
}


//--------------------------------------------------------------//
// Destructor                                                   //
//--------------------------------------------------------------//
ToDoList::~ToDoList()
{
    FreeTranslatedMenu(m_pCategoryMenu);
}


//--------------------------------------------------------------//
// Category selection has been changed, filter the ToDo List    //
// entries                                                      //
//--------------------------------------------------------------//
void
ToDoList::CategorySelected(Fl_Widget * pWidget, void *pUserData)
{
    ToDoList *pThis = reinterpret_cast < ToDoList * >(pWidget->parent());

    // Filter rows based on category
    // Get the category value -1 so that -1 is the All category
    pThis->Filter((reinterpret_cast < Fl_Choice * >(pWidget))->value() - 1);
}


//--------------------------------------------------------------//
// Copy a row to m_strCopyString.                               //
//--------------------------------------------------------------//
int
ToDoList::Copy(int nRow)
{
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();
    int nReturn;

    if (nRow >= 0) {
	// Save any outstanding changes
	SaveDetailChanges();

	// Copy this row
	pToDoListDB->Export(nRow, m_vCopyString);
	PixilDT::GetApp()->GetMainWindow()->Notify(FIX_MENU, 0);
	nReturn = 1;
    } else {
	// No row to copy
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Cut a row to m_strCopyString.                                //
//--------------------------------------------------------------//
int
ToDoList::Cut(int nRow)
{
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();
    int nReturn;

    if (nRow >= 0) {
	// Save any outstanding changes
	SaveDetailChanges();

	// Copy this row
	pToDoListDB->Export(nRow, m_vCopyString);
	pToDoListDB->Delete(nRow);
	pToDoListDB->Save();
	m_bUndoCut = true;
	m_bUndoPaste = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(TODO_LIST_CHANGED, 0);
	nReturn = 1;
    } else {
	// No row to copy
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Confirm the deletion of a ToDo item.                         //
//--------------------------------------------------------------//
void
ToDoList::Delete(int nRow)
{
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();
    int nContinue;

    if (Options::GetConfirmDelete() == true) {
	nContinue = fl_ask(_("Delete To Do Item: %s ?"),
			   pToDoListDB->GetTitle(nRow).c_str());
    } else {
	nContinue = 1;
    }

    if (nContinue == 1) {
	pToDoListDB->Delete(nRow);
	pToDoListDB->Save();
	PixilDT::GetApp()->GetMainWindow()->Notify(TODO_LIST_CHANGED, 0);
    }
}


//--------------------------------------------------------------//
// Insert a new entry via the dialog.                           //
//--------------------------------------------------------------//
void
ToDoList::EditNew()
{
    int nCategory;
    int nRecno;
    int nRow;
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();
    ToDoListCategoryDB *pToDoListCategoryDB =
	ToDoListCategoryDB::GetToDoListCategoryDB();

    // Create a new todo item
    nCategory = m_pCategory->value() - 1;
    if (nCategory >= 0) {
	nCategory = pToDoListCategoryDB->GetCategoryID(nCategory);
    } else {
	nCategory = 0;
    }
    nRow = pToDoListDB->Insert(m_pCategory->value() - 1);
    nRecno = pToDoListDB->GetID(nRow);

    // OK button was pressed, refresh displays
    PixilDT::GetApp()->GetMainWindow()->Notify(TODO_LIST_CHANGED, 0);

    // Select the row just added or updated
    m_pToDoListList->SelectRow(pToDoListDB->FindRow(TODO_ID, nRecno));
}


//--------------------------------------------------------------//
// Change any line with a category just deleted back to Unfiled //
//--------------------------------------------------------------//
void
ToDoList::FixDeletedCategory(int nCategory)
{
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();
    int nMax = pToDoListDB->NumRecs();
    int nRow;

    for (nRow = 0; nRow < nMax; ++nRow) {
	if (pToDoListDB->IsDeleted(nRow) == false) {
	    if (pToDoListDB->GetCategory(nRow) == nCategory) {
		// "0" should be the "Unfiled" category
		pToDoListDB->SetCategory(nRow, 0);
	    }
	}
    }
    pToDoListDB->Save();
}


//--------------------------------------------------------------//
// Process a message from the parent widget.                    //
//--------------------------------------------------------------//
int
ToDoList::Message(PixilDTMessage nMessage, int nInfo)
{
    int nReturn = 0;		// Default return value

    switch (nMessage) {
    case SHOW_TODO_OPTIONS:
	// Show the ToDo list options dialog
	ViewShow();
	break;

    case TODO_LIST_CATEGORY_ADDED:
	// Fix and reset the category choice
	ResetCategoryChoice();
	break;

    case TODO_LIST_CATEGORY_DELETED:
	// Fix all ToDo entries with this category to be Unfiled
	FixDeletedCategory(nInfo);

	// Fix and reset the category choice
	ResetCategoryChoice();

	// Refresh the ToDo List
	m_pToDoListList->Refresh();
	break;

    case TODO_LIST_CATEGORY_RENAMED:
	// Fix and reset the category choice
	ResetCategoryChoice();

	// Refresh the ToDo List
	m_pToDoListList->Refresh();
	break;

    case TODO_LIST_CHANGED:	// The todo list has been changed
	m_pToDoListList->Refresh();
	break;

    case TODO_LIST_DELETE:	// Delete the current item
	Delete(m_pToDoListList->GetRealRow());
	break;

    case TODO_LIST_GOTO:	// Find dialog requested a ToDo List item, have the list do it
	m_pToDoListList->Message(nMessage, nInfo);
	break;

    case TODO_LIST_NEW:	// Insertion of a new to do list entry has been requested
	EditNew();
	break;

    case TODO_LIST_PRINT:	// Print the To Do List
	m_pToDoListList->Print();
	break;

    case TODO_LIST_REQUESTED:	// Selection changing, no processing needed
    case APPLICATION_CLOSING:	// No processing needed, alredy saved if going to
	break;

    case ADDRESS_BOOK_REQUESTED:	// Selection changing, save if needed
    case NOTES_REQUESTED:	// Selection changing, save if needed
    case SCHEDULER_REQUESTED:	// Selection changing, save if needed
    case SELECTION_CHANGING:	// Save if needed
	nReturn = m_pToDoListDetails->SaveChanges(true);
	break;

    case EDIT_COPY:		// Copy the currently selected line
	nReturn = Copy(m_pToDoListList->GetRealRow());
	break;

    case EDIT_CUT:		// Cut the currently selected line
	nReturn = Cut(m_pToDoListList->GetRealRow());
	break;

    case EDIT_PASTE:		// Paste a prior copy or cut
	nReturn = Paste();
	break;

    case EDIT_UNDO:		// Undo a prior cut/paste
	nReturn = Undo();
	break;

    case EDIT_COPY_AVAILABLE:	// Can a row be cut or copied
    case EDIT_CUT_AVAILABLE:
	nReturn = (m_pToDoListList->rows() > 0
		   && m_pToDoListList->row() >= 0);
	break;

    case EDIT_PASTE_AVAILABLE:	// Has a row been cut or copied
	nReturn = (m_vCopyString.size() > 0);
	break;

    case EDIT_UNDO_AVAILABLE:	// Can the last cut/paste be undone
	nReturn = (m_bUndoCut | m_bUndoPaste ? 1 : 0);
	break;

    default:
#ifdef DEBUG
	assert(false);		// Unknown message
#endif
	;
    }

    return (nReturn);
}


//--------------------------------------------------------------//
// Paste the most recently cut row.                             //
//--------------------------------------------------------------//
int
ToDoList::Paste()
{
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();
    int nReturn;

    if (m_vCopyString.size() > 0) {
	// Save any outstanding changes
	SaveDetailChanges();

	m_nLastPaste = pToDoListDB->Import(m_vCopyString);
	pToDoListDB->Save();
	m_bUndoPaste = true;
	m_bUndoCut = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(TODO_LIST_CHANGED, 0);
	nReturn = 1;
    } else {
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Reset the category choice widget after a category deletion.  //
//--------------------------------------------------------------//
void
ToDoList::ResetCategoryChoice()
{
    FreeTranslatedMenu(m_pCategoryMenu);
    m_pCategoryMenu =
	ToDoListCategoryDB::GetToDoListCategoryDB()->GetCategoryMenu(true);
    m_pCategory->menu(m_pCategoryMenu);
}


//--------------------------------------------------------------//
// Undo the most recent cut or paste                            //
//--------------------------------------------------------------//
int
ToDoList::Undo()
{
    ToDoListDB *pToDoListDB = ToDoListDB::GetToDoListDB();
    int nReturn;

    if (m_bUndoCut == true) {
	// Save any pending changes
	SaveDetailChanges();

	// Insert this row back
	pToDoListDB->Import(m_vCopyString);
	pToDoListDB->Save();
	m_bUndoCut = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(TODO_LIST_CHANGED, 0);
	nReturn = 1;
    } else if (m_bUndoPaste == true) {
	// Delete this row
	pToDoListDB->Delete(m_nLastPaste);
	pToDoListDB->Save();
	m_bUndoPaste = false;
	PixilDT::GetApp()->GetMainWindow()->Notify(TODO_LIST_CHANGED, 0);
	nReturn = 1;
    } else {
	nReturn = 0;
    }
    return (nReturn);
}


//--------------------------------------------------------------//
// Change the view options via the dialog.                      //
//--------------------------------------------------------------//
void
ToDoList::ViewShow()
{
    ToDoListShowDlg *pDlg =
	new ToDoListShowDlg(PixilDT::GetApp()->GetMainWindow());

    if (pDlg->DoModal() == 1) {
	m_pToDoListList->Refresh();
    }
    delete pDlg;
}

--- NEW FILE: Note.h ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */

//--------------------------------------------------------------//
// A note saved from any of the four info types                 //
//--------------------------------------------------------------//
#ifndef NOTE_H_

#define NOTE_H_

#ifdef WIN32
#pragma warning(disable:4786)
#define inline __inline
#endif /*  */

#include <string>
using namespace std;
class Note
{
  public:Note(const char *pszFileName,
	 // Construct from a file
	 int nMaxLength = 0, const char *pszPrefix = NULL);
      Note(int nMaxLength = 0,	// Construct as empty
	   const char *pszPrefix = NULL);
     ~Note();			// Destructor
    void Delete();		// Delete this note - delete its file
    inline const string GetFileName() const	// Get the file name for this note
    {
	return (m_strFileName);
    }
    inline int GetMaxLength() const	// Get the maximum length for this note
    {
	return (m_nMaxLength);
    }
    inline const string GetText() const	// Get the text of the note
    {
	return (m_strText);
    }
    inline bool IsChanged() const	// Has this note been changed
    {
	return (m_bChanged);
    }
    void Save();		// Save this note to disk
    void SetText(const char *pszText);	// Change the text
  private:  bool m_bChanged;	// Has the text changed or not
    int m_nMaxLength;		// Maximum length for the text of this note
    string m_strFileName;	// The note file name
    string m_strPrefix;		// Prefix for note file names
    string m_strText;		// The text of the note
    void CreateFileName();	// Create a file name for this note
};


#endif /*  */

--- NEW FILE: SchedulerWeekly.cpp ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *