unit dlgCategoryManager;

{
[dlgCategoryManager] [1.3]
Delphi 2005
November 2008

LICENSE

The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
"http://www.mozilla.org/MPL/"

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is "[dlgCategoryManager.pas] and [dlgCategoryManager.dfm]".

The Initial Developer of the Original Code is Martin Holmes (Victoria,
BC, Canada, "http://www.mholmes.com/"). Copyright (C) 2005-2008 Martin Holmes
and the University of Victoria Computing and Media Centre. The code was 
co-developed for university and personal projects, and rights are shared
by Martin Holmes and the University of Victoria. All Rights Reserved.
}

{
Written by Martin Holmes, Spring 2006; updated several times.

This unit provides a GUI for browsing, selecting and configuring annotations
and annotation categories. It links in to a TIMTDocument object, which is
the currently-loaded document in the main application window, and it displays
the titles of annotations sorted by category, as well as allowing the user to
set the properties of individual categories.

Dependencies:

TntUnicodeControls (Troy Wolbrink)
FormState for saving size/position etc.
JEDI JCL and JVCL (Project JEDI)

}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TntForms, ComCtrls, TntComCtrls, StdCtrls, Buttons, TntButtons,
  FormState, Main, AppEvnts, jclUnicode, TntDialogs, TntSysUtils, TntStdCtrls,
  ExtCtrls, TntExtCtrls;

type
  TufrmCategoryManager = class(TTntForm)
    ubnCatManClose: TTntBitBtn;
    ubnEditCategory: TTntBitBtn;
    ubnDeleteCategory: TTntBitBtn;
    ulvCategories: TTntListView;
    ubnAddCategory: TTntBitBtn;
    aeCategoryManager: TApplicationEvents;
    usbUp: TTntSpeedButton;
    usbDown: TTntSpeedButton;
    upnCategoryColumns: TTntPanel;
    upnCatIDCaption: TTntPanel;
    usplColumnCaptions: TTntSplitter;
    upnTitleDescCaption: TTntPanel;
    ulbmsgTranscriptional: TTntLabel;
    procedure usplColumnCaptionsMoved(Sender: TObject);
    procedure usbDownClick(Sender: TObject);
    procedure usbUpClick(Sender: TObject);
    procedure ubnDeleteCategoryClick(Sender: TObject);
    procedure ulvCategoriesDblClick(Sender: TObject);
    procedure ubnEditCategoryClick(Sender: TObject);
    procedure ubnAddCategoryClick(Sender: TObject);
    procedure aeCategoryManagerIdle(Sender: TObject; var Done: Boolean);
    procedure TntFormShow(Sender: TObject);
    procedure ulvCategoriesResize(Sender: TObject);
    procedure TntFormDestroy(Sender: TObject);
    procedure TntFormCreate(Sender: TObject);
  private
    FFormStateSaver: TFormStateSaver;

    { Private declarations }
  public
    procedure PopulateListBox;
    procedure WriteNewCatDataToDoc;
    { Public declarations }
  end;

var
  ufrmCategoryManager: TufrmCategoryManager;

implementation

uses dlgAnnCat, dlgCategoryProperties;

{$R *.DFM}



procedure TufrmCategoryManager.TntFormCreate(Sender: TObject);
begin
  FFormStateSaver := TFormStateSaver.Create(Self, True, True, False, False, False,
                                            False, False, False, False);
end;

procedure TufrmCategoryManager.TntFormDestroy(Sender: TObject);
begin
  FreeAndNil(FFormStateSaver);
end;

procedure TufrmCategoryManager.ulvCategoriesResize(Sender: TObject);
var
ScrollbarW: integer;
ListViewBottom: integer;

begin
  ScrollbarW := GetSystemMetrics(SM_CXVSCROLL);
  ulvCategories.Columns[1].Width := ulvCategories.Width -
            (ulvCategories.Columns[0].Width + ScrollbarW + 10);
  ListViewBottom := ulvCategories.Top + ulvCategories.Height;
  ulvCategories.Top := upnCategoryColumns.Top + upnCategoryColumns.Height;
  ulvCategories.Height := ListViewBottom - ulvCategories.Top;
end;

procedure TufrmCategoryManager.TntFormShow(Sender: TObject);
begin
  PopulateListBox;
end;

procedure TufrmCategoryManager.PopulateListBox;
var
i: integer;
ListItem: TTntListItem;
var Sub: WideString;

begin
  ulvCategories.Clear;
  if ufrmMain.IMTDoc <> nil then
    if ufrmMain.IMTDoc.AnnCatList.Count > 0 then
      for i := 0 to ufrmMain.IMTDoc.AnnCatList.Count-1 do
        begin
          ListItem := ulvCategories.Items.Add;
          ListItem.Caption := ufrmMain.IMTDoc.AnnCatList.ID[i];
          Sub := ufrmMain.IMTDoc.AnnCatList.Explanation[i];
          if ufrmMain.IMTDoc.AnnCatList.Transcriptional[i] then
            Sub := Sub + ' ' + ulbmsgTranscriptional.Caption;
          ListItem.SubItems.Add(Sub);
        end;
end;

procedure TufrmCategoryManager.aeCategoryManagerIdle(Sender: TObject;
  var Done: Boolean);
begin
  ubnEditCategory.Enabled := (ulvCategories.ItemIndex > -1);
  ubnDeleteCategory.Enabled := (ulvCategories.ItemIndex > -1);

{Determine whether the up and down buttons should be enabled, based on
whether there's a meaningful movement that can be made with them.
Multi-selection is not allowed in the case of this control.}
  usbUp.Enabled := (ulvCategories.ItemIndex > 0);
  usbDown.Enabled := ((ulvCategories.ItemIndex < (ulvCategories.Items.Count-1)) and
                      (ulvCategories.ItemIndex >= 0));
end;

procedure TufrmCategoryManager.ubnAddCategoryClick(Sender: TObject);
begin
  if ufrmAnnCat.AddNewCategory > -1 then
    PopulateListBox;
end;

procedure TufrmCategoryManager.ubnEditCategoryClick(Sender: TObject);
var
CatNum: integer;
OldCatID: WideString;
NewCatID: WideString;
OldExplanation: WideString;
OldTranscriptional: Boolean;

begin
//Sanity check
  if ulvCategories.ItemIndex < 0 then
    Exit;
//First, find the category information for the selected category.
  CatNum := ulvCategories.ItemIndex;
  OldCatID := ufrmMain.IMTDoc.AnnCatList.ID[CatNum];
  OldExplanation := ufrmMain.IMTDoc.AnnCatList.Explanation[CatNum]; //why do we need this?
  OldTranscriptional := ufrmMain.IMTDoc.AnnCatList.Transcriptional[CatNum]; //why do we need this?
//Now populate the properties form
  ufrmAnnCat.PopulateCategoryPropsForm(CatNum);

//Show it for editing
  ufrmCategoryProperties.ShowModal;

//When editing is finished, set it back to -1;
  ufrmCategoryProperties.CatNum := -1;

end;

procedure TufrmCategoryManager.WriteNewCatDataToDoc;
var
OldCatID, NewCatID: WideString;

begin
  if ufrmCategoryProperties.CatNum < 0 then
    Exit; //This is a new category; let the calling procedure handle it.
  if not (ufrmCategoryProperties.CatNum in [0..ufrmMain.IMTDoc.AnnCatList.Count-1]) then
    Exit; //Screw up somehow; index is out of range.

  NewCatID := WideTrim(ufrmCategoryProperties.uedCategoryID.Text);

//Set the properties. This will automatically trigger redraws in the image layers
//if necessary...
  ufrmMain.IMTDoc.SetCategoryProperties(ufrmCategoryProperties.CatNum,
                              ufrmCategoryProperties.SelectedShape,
                              ufrmCategoryProperties.jvcolcmbCatColor.ColorValue,
                              ufrmCategoryProperties.uedCategoryDescription.Text,
                              ufrmCategoryProperties.ucbTranscriptional.Checked,
                              NewCatID);

//...but it won't update the ufrmAnnCat UI, so we need to figure out whether
//anything significant to that UI has changed. At this point, that means the
//categoryid.
  if OldCatID <> NewCatID then
    begin
      ufrmAnnCat.CategoryIDChanged(OldCatID, NewCatID);
    end;

  PopulateListBox;
end;

procedure TufrmCategoryManager.ulvCategoriesDblClick(Sender: TObject);
begin
  if ulvCategories.ItemIndex > -1 then
    ubnEditCategoryClick(ubnEditCategory);
end;

procedure TufrmCategoryManager.ubnDeleteCategoryClick(Sender: TObject);
begin
//Sanity check
  if ulvCategories.ItemIndex < 0 then
    Exit;
  if ufrmAnnCat.DeleteCategory(ulvCategories.ItemIndex) then
    PopulateListBox;
end;

procedure TufrmCategoryManager.usbUpClick(Sender: TObject);
var
SelItem: integer;

begin
  SelItem := ulvCategories.ItemIndex;
  if SelItem > 0 then
    if ufrmMain.IMTDoc.SwapCategories(SelItem, SelItem-1) then
      begin
        PopulateListBox;
        ulvCategories.ItemIndex := SelItem-1;
        ufrmAnnCat.InitializeCategories;
      end;
end;

procedure TufrmCategoryManager.usbDownClick(Sender: TObject);
var
SelItem: integer;

begin
  SelItem := ulvCategories.ItemIndex;
  if SelItem < (ulvCategories.Items.Count-1) then
    if ufrmMain.IMTDoc.SwapCategories(SelItem, SelItem+1) then
      begin
        PopulateListBox;
        ulvCategories.ItemIndex := SelItem+1;
        ufrmAnnCat.InitializeCategories;
      end;
end;

procedure TufrmCategoryManager.usplColumnCaptionsMoved(Sender: TObject);
begin
  ulvCategories.Columns[0].Width := upnCatIDCaption.Width;
end;



end.
