{$A+,B-,C+,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,N+,O-,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y-,Z1}
{$MINSTACKSIZE $00004000}
{$MAXSTACKSIZE $00100000}
{$IMAGEBASE $00400000}
{$APPTYPE GUI}
unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, RXSpin, RXCombos, ExtCtrls, RXCtrls, Buttons,
  Grids, ExtDlgs, checklst, RXSplit, SpeedBar, RxGif, jpeg, {$IFNDEF VER100} ImgList,{$ENDIF} O2Plan, PEConsts, MRUList, Registry, Placemnt,
  ComCtrls, ShellApi, ClipBrd, ClipMon, PlanObjects, Printers, PlanUtils;

type
  TMainForm = class(TForm)
    MainMenu1: TMainMenu;
    PlanMenu: TMenuItem;
    PlanOpenItem: TMenuItem;
    PlanSaveItem: TMenuItem;
    PlanSaveAsItem: TMenuItem;
    N1: TMenuItem;
    ExitItem: TMenuItem;
    LayerMenu: TMenuItem;
    LayerAddItem: TMenuItem;
    LayerDeleteItem: TMenuItem;
    LayerRenameItem: TMenuItem;
    Panel1: TPanel;
    FontGroupBox: TGroupBox;
    FontCombo: TFontComboBox;
    FontSizeEdit: TRxSpinEdit;
    FontBoldButton: TRxSpeedButton;
    FontItalicButton: TRxSpeedButton;
    FontUnderlineButton: TRxSpeedButton;
    PenGroupBox: TGroupBox;
    ToolsPanel: TPanel;
    ScaleMenu: TMenuItem;
    ScaleZoomItem: TMenuItem;
    ScaleUnzoomItem: TMenuItem;
    BottomPanel: TPanel;
    InfoPanel: TPanel;
    PlanScrollBox: TScrollBox;
    PenStyleCombo: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    PenWidthEdit: TRxSpinEdit;
    BrushGroupBox: TGroupBox;
    Label3: TLabel;
    BrushStyleCombo: TComboBox;
    LayersGroupBox: TGroupBox;
    LayersListBox: TCheckListBox;
    ScaleGroupBox: TGroupBox;
    ScaleXEdit: TRxSpinEdit;
    ScaleYEdit: TRxSpinEdit;
    Label4: TLabel;
    RxSplitter1: TRxSplitter;
    RxSplitter2: TRxSplitter;
    PropertiesPanel: TPanel;
    PropertiessCommonPanel: TPanel;
    Label5: TLabel;
    ObjectNameEdit: TEdit;
    Label6: TLabel;
    ObjectIDEdit: TRxSpinEdit;
    Label7: TLabel;
    ObjectChildrenGroupBox: TGroupBox;
    ObjectChildrenCombo: TComboBox;
    SelectButton: TSpeedButton;
    DrawLineButton: TSpeedButton;
    DrawBoxButton: TSpeedButton;
    DrawCircleButton: TSpeedButton;
    DrawTextButton: TSpeedButton;
    DrawPictureButton: TSpeedButton;
    DrawPolygonButton: TSpeedButton;
    Panel3: TPanel;
    BrushColorBox: TPaintBox;
    PenColorBox: TPaintBox;
    ColorGrid: TDrawGrid;
    PlanOpenDialog: TOpenDialog;
    PlanSaveDialog: TSaveDialog;
    PlanEditorSpeedBar: TSpeedBar;
    SpeedbarSection1: TSpeedbarSection;
    OpenButton: TSpeedItem;
    SaveButton: TSpeedItem;
    LayerAddButton: TSpeedItem;
    LayerDeleteButton: TSpeedItem;
    ZoomInButton: TSpeedItem;
    ZoomOutButton: TSpeedItem;
    ExitButton: TSpeedItem;
    LayerRenameButton: TSpeedItem;
    CurObjectPanel: TPanel;
    ObjectMenu: TMenuItem;
    ObjectAddPropertyItem: TMenuItem;
    ObjectDeletePropertyItem: TMenuItem;
    ObjectSavePropertiesItem: TMenuItem;
    N3: TMenuItem;
    ObjectApplyPropertiesButton: TBitBtn;
    ObjectPropertiesGrid: TStringGrid;
    SelectPictureDialog: TOpenPictureDialog;
    ColorDialog: TColorDialog;
    ObjectChildSelectButton: TSpeedButton;
    ObjectDeleteItem: TMenuItem;
    PlanNewItem: TMenuItem;
    N2: TMenuItem;
    Scale100Item: TMenuItem;
    DrawAniPictureButton: TSpeedButton;
    DrawAniGifButton: TSpeedButton;
    SelectAniPictureDialog: TOpenPictureDialog;
    SelectAniGifDialog: TOpenPictureDialog;
    StatusPanel: TPanel;
    StartStopImageList: TImageList;
    StartStopAnimateButton: TSpeedItem;
    BackgroundMenu: TMenuItem;
    BackgroundPictrureRemoveItem: TMenuItem;
    BackgroundPictureSelectItem: TMenuItem;
    PlanInfoPanel: TPanel;
    ObjectLayerCombo: TComboBox;
    N4: TMenuItem;
    ObjectStartBlinkItem: TMenuItem;
    ObjectStopBlinkItem: TMenuItem;
    Panel2: TPanel;
    LayerReadOnlyCheck: TCheckBox;
    HelpMenu: TMenuItem;
    N5: TMenuItem;
    StandardPicturesItem: TMenuItem;
    StandardAniGifsItem: TMenuItem;
    ObjectReadOnlyCheck: TCheckBox;
    ActualSizeButton: TSpeedItem;
    FormatMenu: TMenuItem;
    FormatFontItem: TMenuItem;
    FontSelectDialog: TFontDialog;
    BackgroundColorItem: TMenuItem;
    ColorSelectDialog: TColorDialog;
    LayerObjectCountLabel: TLabel;
    PlanMRUManager: TMRUManager;
    FileReopenMenu: TMenuItem;
    N6: TMenuItem;
    FindObjectItem: TMenuItem;
    ObjectSelectByColorItem: TMenuItem;
    ObjectUnselectColorItem: TMenuItem;
    N7: TMenuItem;
    FormPlacement1: TFormPlacement;
    Label27: TLabel;
    Bevel1: TBevel;
    ObjectParentLabel: TLabel;
    CloneObjectItem: TMenuItem;
    FontColorPanel: TPanel;
    ParseProgressBar: TProgressBar;
    ObjectCopyItem: TMenuItem;
    ObjectPasteItem: TMenuItem;
    ViewAutoAnimateItem: TMenuItem;
    ViewChildrenClippingItem: TMenuItem;
    ExportMenu: TMenuItem;
    ExportBitmapItem: TMenuItem;
    ExportMetafileItem: TMenuItem;
    ExportJpegItem: TMenuItem;
    ExportGIFItem: TMenuItem;
    N8: TMenuItem;
    PlanCopyToClipboardItem: TMenuItem;
    SavePictureDialog: TSavePictureDialog;
    DrawEllipseButton: TSpeedButton;
    TransparentCheck: TCheckBox;
    Image1: TImage;
    Plan: TOxygenPlan;
    DrawPolyLineButton: TSpeedButton;
    DrawTraceLineButton: TSpeedButton;
    SavePicturesItem: TMenuItem;
    SaveBackgroundPictureItem: TMenuItem;
    SaveStandardPicturesItem: TMenuItem;
    PlanPaintToDesktopItem: TMenuItem;
    N9: TMenuItem;
    PrintSetupItem: TMenuItem;
    PrintItem: TMenuItem;
    PlanCopyToClipboardButton: TSpeedItem;
    NewPlanButton: TSpeedItem;
    PrintSetupButton: TSpeedItem;
    PrintButton: TSpeedItem;
    PrinterSetupDialog1: TPrinterSetupDialog;
    PrintDialog1: TPrintDialog;
    FindObjectButton: TSpeedItem;
    ObjectCloneButton: TSpeedItem;
    CopyObjectButton: TSpeedItem;
    ObjectPasteButton: TSpeedItem;
    ObjectDeleteButton: TSpeedItem;
    PrintWhiteReplacementColorItem: TMenuItem;
    N10: TMenuItem;
    ObjectMoveItem: TMenuItem;
    ObjectResizeItem: TMenuItem;
    WWWButton: TSpeedItem;
    WWWItem: TMenuItem;
    ViewDoubleBufferedItem: TMenuItem;
    ObjectPageControl: TPageControl;
    ObjectCommonTabSheet: TTabSheet;
    PropertiesNotebook: TNotebook;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    LineX1Edit: TRxSpinEdit;
    LineY1Edit: TRxSpinEdit;
    LineX2Edit: TRxSpinEdit;
    LineY2Edit: TRxSpinEdit;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    BoxX1Edit: TRxSpinEdit;
    BoxY1Edit: TRxSpinEdit;
    BoxX2Edit: TRxSpinEdit;
    BoxY2Edit: TRxSpinEdit;
    Label36: TLabel;
    Label37: TLabel;
    Label38: TLabel;
    CircleXEdit: TRxSpinEdit;
    CircleYEdit: TRxSpinEdit;
    CircleRadiusEdit: TRxSpinEdit;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label39: TLabel;
    Label40: TLabel;
    TextX1Edit: TRxSpinEdit;
    TextY1Edit: TRxSpinEdit;
    TextX2Edit: TRxSpinEdit;
    TextY2Edit: TRxSpinEdit;
    TextEdit: TEdit;
    TextAlignmentCombo: TComboBox;
    TextBorderCheck: TCheckBox;
    Label20: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label26: TLabel;
    PictureX1Edit: TRxSpinEdit;
    PictureY1Edit: TRxSpinEdit;
    PictureX2Edit: TRxSpinEdit;
    PictureY2Edit: TRxSpinEdit;
    SelectPictureButton: TBitBtn;
    StdPictureCombo: TComboBox;
    PictureTransparentCheck: TCheckBox;
    Label41: TLabel;
    Label42: TLabel;
    Label43: TLabel;
    Label44: TLabel;
    Label50: TLabel;
    Label25: TLabel;
    Label29: TLabel;
    AniPictureX1Edit: TRxSpinEdit;
    AniPictureY1Edit: TRxSpinEdit;
    AniPictureY2Edit: TRxSpinEdit;
    AniPictureX2Edit: TRxSpinEdit;
    SelectAniPictureButton: TBitBtn;
    AniPictureFramesEdit: TRxSpinEdit;
    StdAniPictureCombo: TComboBox;
    AniPictureFrameEdit: TRxSpinEdit;
    Label45: TLabel;
    Label46: TLabel;
    Label47: TLabel;
    Label48: TLabel;
    Label49: TLabel;
    Label24: TLabel;
    Label28: TLabel;
    AniGifX1Edit: TRxSpinEdit;
    AniGifY1Edit: TRxSpinEdit;
    AniGifY2Edit: TRxSpinEdit;
    AniGifX2Edit: TRxSpinEdit;
    SelectAniGifButton: TBitBtn;
    AniGifFramesPanel: TPanel;
    StdAniGifCombo: TComboBox;
    AniGifFrameEdit: TRxSpinEdit;
    ObjectGradientTabSheet: TTabSheet;
    GradientActiveCheck: TCheckBox;
    Label30: TLabel;
    GradientStartColorPanel: TPanel;
    Label31: TLabel;
    GradientEndColorPanel: TPanel;
    Label32: TLabel;
    GradientColorsEdit: TRxSpinEdit;
    Label33: TLabel;
    GradientDirectionCombo: TComboBox;
    Label34: TLabel;
    TextEscapementEdit: TRxSpinEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure ExitItemClick(Sender: TObject);
    procedure PenStyleComboDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
    procedure BrushStyleComboDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
    procedure ColorGridDrawCell(Sender: TObject; Col, Row: Integer; Rect: TRect; State: TGridDrawState);
    procedure ColorGridMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure PenColorBoxPaint(Sender: TObject);
    procedure BrushColorBoxPaint(Sender: TObject);
    procedure PenStyleComboClick(Sender: TObject);
    procedure PenWidthEditChange(Sender: TObject);
    procedure BrushStyleComboClick(Sender: TObject);
    procedure ScaleXEditChange(Sender: TObject);
    procedure ScaleYEditChange(Sender: TObject);
    procedure PlanOpenItemClick(Sender: TObject);
    procedure PlanSaveItemClick(Sender: TObject);
    procedure PlanSaveAsItemClick(Sender: TObject);
    procedure ScaleZoomItemClick(Sender: TObject);
    procedure ScaleUnzoomItemClick(Sender: TObject);
    procedure LayersListBoxClick(Sender: TObject);
    procedure LayersListBoxClickCheck(Sender: TObject);
    procedure PlanEditorSpeedBarResize(Sender: TObject);
    procedure PenColorBoxDblClick(Sender: TObject);
    procedure BrushColorBoxDblClick(Sender: TObject);
    procedure PlanObjectClick(Plan: TOxygenPlan; PlanObject: TPlanObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FontComboClick(Sender: TObject);
    procedure FontSizeEditChange(Sender: TObject);
    procedure FontBoldButtonClick(Sender: TObject);
    procedure ObjectSavePropertiesItemClick(Sender: TObject);
    procedure LineX1EditChange(Sender: TObject);
    procedure BoxX1EditChange(Sender: TObject);
    procedure CircleXEditChange(Sender: TObject);
    procedure TextX1EditChange(Sender: TObject);
    procedure TextEditChange(Sender: TObject);
    procedure TextAlignmentComboClick(Sender: TObject);
    procedure PictureX1EditChange(Sender: TObject);
    procedure SelectPictureButtonClick(Sender: TObject);
    procedure LayerAddItemClick(Sender: TObject);
    procedure LayerDeleteItemClick(Sender: TObject);
    procedure LayerRenameItemClick(Sender: TObject);
    procedure ObjectAddPropertyItemClick(Sender: TObject);
    procedure ObjectDeleteItemClick(Sender: TObject);
    procedure DrawLineButtonClick(Sender: TObject);
    procedure DrawBoxButtonClick(Sender: TObject);
    procedure DrawCircleButtonClick(Sender: TObject);
    procedure DrawTextButtonClick(Sender: TObject);
    procedure DrawPictureButtonClick(Sender: TObject);
    procedure DrawPolygonButtonClick(Sender: TObject);
    procedure PlanAfterDrawNewObject(Plan: TOxygenPlan; PlanObject: TPlanObject);
    procedure SelectButtonClick(Sender: TObject);
    procedure PlanNewItemClick(Sender: TObject);
    procedure Scale100ItemClick(Sender: TObject);
    procedure DrawAniPictureButtonClick(Sender: TObject);
    procedure DrawAniGifButtonClick(Sender: TObject);
    procedure AniPictureX1EditChange(Sender: TObject);
    procedure AniPictureFramesEditChange(Sender: TObject);
    procedure SelectAniPictureButtonClick(Sender: TObject);
    procedure AniGifX1EditChange(Sender: TObject);
    procedure SelectAniGifButtonClick(Sender: TObject);
    procedure PlanObjectMouseMove(Plan: TOxygenPlan; PlanObject: TPlanObject);
    procedure StartStopAnimateButtonClick(Sender: TObject);
    procedure BackgroundPictureSelectItemClick(Sender: TObject);
    procedure BackgroundPictrureRemoveItemClick(Sender: TObject);
    procedure ObjectLayerComboClick(Sender: TObject);
    procedure LayerReadOnlyCheckClick(Sender: TObject);
    procedure StandardPicturesItemClick(Sender: TObject);
    procedure StandardAniGifsItemClick(Sender: TObject);
    procedure StdPictureComboClick(Sender: TObject);
    procedure StdAniPictureComboClick(Sender: TObject);
    procedure StdAniGifComboClick(Sender: TObject);
    procedure ObjectChildSelectButtonClick(Sender: TObject);
    procedure ObjectReadOnlyCheckClick(Sender: TObject);
    procedure PictureTransparentCheckClick(Sender: TObject);
    procedure FormatFontItemClick(Sender: TObject);
    procedure BackgroundColorItemClick(Sender: TObject);
    procedure ObjectDeletePropertyItemClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure PlanMRUManagerClick(Sender: TObject; const RecentName, Caption: String; UserData: Integer);
    procedure FindObjectItemClick(Sender: TObject);
    procedure ObjectSelectByColorItemClick(Sender: TObject);
    procedure ObjectUnselectColorItemClick(Sender: TObject);
    procedure ObjectParentLabelClick(Sender: TObject);
    procedure CloneObjectItemClick(Sender: TObject);
    procedure FontColorPanelClick(Sender: TObject);
    procedure PlanParseProgress(Plan: TOxygenPlan; const PercentsCompleted: Integer);
    procedure TextBorderCheckClick(Sender: TObject);
    procedure ObjectCopyItemClick(Sender: TObject);
    procedure ObjectPasteItemClick(Sender: TObject);
    procedure ViewAutoAnimateItemClick(Sender: TObject);
    procedure ViewChildrenClippingItemClick(Sender: TObject);
    procedure ExportBitmapItemClick(Sender: TObject);
    procedure ExportMetafileItemClick(Sender: TObject);
    procedure ExportJpegItemClick(Sender: TObject);
    procedure ExportGIFItemClick(Sender: TObject);
    procedure PlanCopyToClipboardItemClick(Sender: TObject);
    procedure DrawEllipseButtonClick(Sender: TObject);
    procedure AniGifFrameEditChange(Sender: TObject);
    procedure AniPictureFrameEditChange(Sender: TObject);
    procedure TransparentCheckClick(Sender: TObject);
    procedure DrawPolyLineButtonClick(Sender: TObject);
    procedure DrawTraceLineButtonClick(Sender: TObject);
    procedure PlanNeedPicture(Plan: TOxygenPlan; PlanPicture: TPlanPicture);
    procedure PlanNeedAniGif(Plan: TOxygenPlan; PlanAniGif: TPlanAniGif);
    procedure SavePicturesItemClick(Sender: TObject);
    procedure SaveBackgroundPictureItemClick(Sender: TObject);
    procedure SaveStandardPicturesItemClick(Sender: TObject);
    procedure PlanPaintToDesktopItemClick(Sender: TObject);
    procedure PrintSetupItemClick(Sender: TObject);
    procedure PrintItemClick(Sender: TObject);
    function PlanNeedStdAniGif(Plan: TOxygenPlan; const AniGifName: String): Boolean;
    function PlanNeedStdPicture(Plan: TOxygenPlan; const PictureName: String): Boolean;
    procedure PrintWhiteReplacementColorItemClick(Sender: TObject);
    procedure ObjectMoveItemClick(Sender: TObject);
    procedure ObjectResizeItemClick(Sender: TObject);
    procedure WWWButtonClick(Sender: TObject);
    procedure ViewDoubleBufferedItemClick(Sender: TObject);
    procedure GradientActiveCheckClick(Sender: TObject);
    procedure GradientColorsEditChange(Sender: TObject);
    procedure GradientStartColorPanelClick(Sender: TObject);
    procedure GradientEndColorPanelClick(Sender: TObject);
    procedure GradientDirectionComboChange(Sender: TObject);
    procedure PlanObjectBlink(Plan: TOxygenPlan; PlanObject: TPlanObject);
  private
    { Private declarations }
    FPlanSaved : Boolean;
    FPlanFileName:String;
    FUpdatingData:Boolean;
    FAppTitle:String;
    FClipboardMonitor : TClipboardMonitor;

    procedure UpdateLayersList;
    procedure RefreshButtons;
    procedure RefreshStdImages;
    procedure ReadOptions;
    procedure SaveOptions;
    procedure SetPlanSaved(const Value : Boolean);
    procedure OpenPlan(const FileName : String);
    procedure ClipboardChange(Sender : TObject);
  public
    { Public declarations }
    property PlanSaved : Boolean read FPlanSaved write SetPlanSaved;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

  uses SPManager, SAGManager, BlinkParams, FindObject, MoveResizeDlg;

procedure TMainForm.UpdateLayersList;
  var i:Integer;
begin
  LayersListBox.Items.Clear;
  for i:=1 to Plan.Layers.Count do begin
    LayersListBox.Items.Add(Plan.Layers[i-1].Name);
    LayersListBox.Checked[LayersListBox.Items.Count-1]:=Plan.Layers[i-1].Visible;
  end;
  try LayersListBox.ItemIndex := LayersListBox.Items.IndexOf(Plan.CurrentLayer.Name) except end;
  with ObjectLayerCombo.Items do begin
    Clear;
    AddStrings(LayersListBox.Items);
  end;
  LayerReadOnlyCheck.Checked := Plan.CurrentLayer.ReadOnly;
  RefreshButtons;
end;

procedure TMainForm.RefreshButtons;
begin
  LayerDeleteItem.Enabled:=(Plan.Layers.Count>1);
  LayerDeleteButton.Enabled:=LayerDeleteItem.Enabled;
  ObjectAddPropertyItem.Enabled:=(Plan.ActiveObject<>nil);
  ObjectDeletePropertyItem.Enabled:=ObjectAddPropertyItem.Enabled;
  ObjectDeleteItem.Enabled := ObjectDeletePropertyItem.Enabled;
  ObjectDeleteButton.Enabled := ObjectDeleteItem.Enabled;
  BackgroundPictrureRemoveItem.Enabled := ((Plan.BackgroundPicture<>nil) and (Plan.BackgroundPicture.Graphic<>nil) and (not Plan.BackgroundPicture.Graphic.Empty));
  PlanInfoPanel.Caption := Format(sTotalObjects,[Plan.ObjectCount]);
  LayerObjectCountLabel.Caption := Format(sLayerObjects,[Plan.CurrentLayer.Count]);
end;

procedure TMainForm.RefreshStdImages;
  var i : Integer;
begin
  StdPictureCombo.Items.Clear;
  StdPictureCombo.Items.Add('<Custom>');
  StdAniGifCombo.Items.Clear;
  StdAniGifCombo.Items.Add('<Custom>');
  for i := 1 to Plan.PictureCount do StdPictureCombo.Items.Add(Plan.Pictures[i-1].Name);
  for i := 1 to Plan.AniGifCount do StdAniGifCombo.Items.Add(Plan.AniGifs[i-1].Name);
  StdAniPictureCombo.Items.Clear;
  StdAniPictureCombo.Items.AddStrings(StdPictureCombo.Items);
end;

procedure TMainForm.ReadOptions;
  var f : TRegIniFile;
begin
  f := TRegIniFile.Create('Oxygen Plan Editor');
  PlanMRUManager.LoadFromRegistry(f,'MRUFiles');
  ViewAutoAnimateItem.Checked := f.ReadBool('Options','AutoAnimate',ViewAutoAnimateItem.Checked);
  if ViewAutoAnimateItem.Checked then Plan.Options := Plan.Options + [poAutoAnimate] else Plan.Options := Plan.Options - [poAutoAnimate];
  ViewChildrenClippingItem.Checked := f.ReadBool('Options','ChildrenClipping',ViewChildrenClippingItem.Checked);
  if ViewChildrenClippingItem.Checked then Plan.Options := Plan.Options + [poChildrenClipping] else Plan.Options := Plan.Options - [poChildrenClipping];
  SavePicturesItem.Checked := f.ReadBool('Options','SavePictures',SavePicturesItem.Checked);
  if SavePicturesItem.Checked then Plan.Options := Plan.Options + [poSavePictures] else Plan.Options := Plan.Options - [poSavePictures];
  SaveBackgroundPictureItem.Checked := f.ReadBool('Options','SaveBackgroundPicture',SaveBackgroundPictureItem.Checked);
  if SaveBackgroundPictureItem.Checked then Plan.Options := Plan.Options + [poSaveBackgroundPicture] else Plan.Options := Plan.Options - [poSaveBackgroundPicture];
  SaveStandardPicturesItem.Checked := f.ReadBool('Options','SaveStandardPictures',SaveStandardPicturesItem.Checked);
  if SaveStandardPicturesItem.Checked then Plan.Options := Plan.Options + [poSaveStandardPictures] else Plan.Options := Plan.Options - [poSaveStandardPictures];
  f.Free;
end;

procedure TMainForm.SaveOptions;
  var f : TRegIniFile;
begin
  f := TRegIniFile.Create('Oxygen Plan Editor');
  PlanMRUManager.SaveToRegistry(f,'MRUFiles');
  f.WriteBool('Options','AutoAnimate',ViewAutoAnimateItem.Checked);
  f.WriteBool('Options','ChildrenClipping',ViewChildrenClippingItem.Checked);
  f.WriteBool('Options','SavePictures',SavePicturesItem.Checked);
  f.WriteBool('Options','SaveBackgroundPicture',SaveBackgroundPictureItem.Checked);
  f.WriteBool('Options','SaveStandardPictures',SaveStandardPicturesItem.Checked);
  f.Free;
end;

procedure TMainForm.SetPlanSaved(const Value : Boolean);
begin
  FPlanSaved := Value;
  PlanSaveItem.Enabled := not Value;
  SaveButton.Enabled := not Value;
end;

procedure TMainForm.OpenPlan(const FileName : String);
begin
  with ParseProgressBar do begin
    Position := 0;
    Visible := True;
  end;
  Screen.Cursor := crHourGlass;
  Application.ProcessMessages;
  try
    FPlanFileName := FileName;
    PlanMRUManager.Add(FPlanFileName,0);
    Caption:=FPlanFileName+' - '+FAppTitle;
    Plan.LoadFromFile(FPlanFileName);
    UpdateLayersList;
    RefreshStdImages;
    Plan.Width:=Plan.ScaleX;
    Plan.Height:=Plan.ScaleY;
    ScaleXEdit.Value:=Plan.ScaleX;
    ScaleYEdit.Value:=Plan.ScaleY;
    FontColorPanel.Color := Plan.Font.Color;
  finally
    PlanSaved := True;
    Screen.Cursor := crDefault;
    ParseProgressBar.Visible := False;
  end;
end;

procedure TMainForm.ClipboardChange(Sender : TObject);
begin
  ObjectPasteItem.Enabled := Clipboard.HasFormat(CF_TEXT);
end;

// published
procedure TMainForm.FormCreate(Sender: TObject);
begin
  FAppTitle:=Caption;
  PlanSaved:=True;
  FUpdatingData:=False;
  FPlanFileName := '';
  ObjectPasteItem.Enabled := Clipboard.HasFormat(CF_TEXT);
  FClipboardMonitor := TClipboardMonitor.Create(Self);
  FClipboardMonitor.OnChange := ClipboardChange;
  FClipboardMonitor.Enabled := True;
  FontCombo.FontName := Plan.Font.Name;
  PenStyleCombo.ItemIndex := Integer(Plan.Pen.Style);
  BrushStyleCombo.ItemIndex := Integer(Plan.Brush.Style);
  PenWidthEdit.Value := Plan.Pen.Width;
  PenColorBox.Color := Plan.Pen.Color;
  BrushColorBox.Color := Plan.Brush.Color;
  with ObjectPropertiesGrid do begin
    Cells[0,0] := sPropertyNameHeader;
    Cells[1,0] := sPropertyValueHeader;
  end;
  TextAlignmentCombo.ItemIndex:=0;
  PropertiesNotebook.PageIndex:=0;
  UpdateLayersList;
  RefreshStdImages;
  ReadOptions;
  Plan.ScaleX := ScaleXEdit.AsInteger;
  Plan.ScaleY := ScaleYEdit.AsInteger;
  ObjectPageControl.ActivePageIndex := 0;
  GradientDirectionCombo.ItemIndex := 0;
end;

procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if not PlanSaved then case MessageDlg(sPlanSaveWarning,mtConfirmation,mbYesNoCancel,0) of
    mrYes    : PlanSaveItemClick(Self);
    mrCancel : begin
                 CanClose := False;
                 Exit;
               end;
  end;
  CanClose := (MessageDlg(sExitProgram,mtConfirmation,mbYesNoCancel,0)=mrYes);
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FClipboardMonitor.Enabled := False;
  SaveOptions;
end;

procedure TMainForm.ExitItemClick(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.PenStyleComboDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  with PenStyleCombo.Canvas do begin
    Brush.Color:=clWindow;
    FillRect(Rect);
    with Pen do begin
      Color:=0;
      Width:=1;
      Style:=TPenStyle(Index);
    end;
    with Rect do begin
      MoveTo(Left+3, Top+5);
      LineTo(Right-3, Top+5);
    end;
  end;
end;

procedure TMainForm.BrushStyleComboDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  with BrushStyleCombo.Canvas do begin
    with Pen do begin
      Color:=0;
      Width:=1;
      Style:=psSolid;
    end;
    with Brush do begin
      if (Index=0) then Color:=Plan.Brush.Color else Color:=clWindow;
      Style:=TBrushStyle(Index);
    end;
    FillRect(Rect);
    if (Index=0) then TextOut(Rect.Left+2,Rect.Top,sBrushSolid)
    else if (Index=1) then TextOut(Rect.Left+2,Rect.Top,sBrushClear);
  end;
end;

procedure TMainForm.ColorGridDrawCell(Sender: TObject; Col, Row: Integer; Rect: TRect; State: TGridDrawState);
begin
  with ColorGrid.Canvas do begin
    Brush.Color := PlanColors[Col*16+Row];
    FillRect(Rect);
    if (gdSelected in State) then DrawFocusRect(Rect);
  end;
end;

procedure TMainForm.ColorGridMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  var C: TColor; Rw, Cl: Longint;
begin
  with ColorGrid do begin
    MouseToCell(X, Y, Cl, Rw);
    Row := Rw;
    Col:=Cl;
  end;
  C:=PlanColors[Cl*16+Rw];
  if (SelectButton.Down and (Plan.ActiveObject<>nil)) then with Plan.ActiveObject do begin
    if (ssLeft in Shift) then begin
      Pen.Color := C;
      PenColorBox.Color := C;
      PenColorBox.Repaint;
      PenStyleCombo.Repaint;
      NeedRepaint;
    end
    else if (ssRight in Shift) then begin
      Brush.Color := C;
      BrushColorBox.Color := C;
      BrushColorBox.Repaint;
      BrushStyleCombo.Repaint;
      NeedRepaint;
    end;
  end;
  if (ssLeft in Shift) then Plan.Pen.Color := C
  else if (ssRight in Shift) then Plan.Brush.Color := C;
end;

procedure TMainForm.PenColorBoxPaint(Sender: TObject);
begin
  with PenColorBox.Canvas do begin
    Brush.Color:=PenColorBox.Color;
    Brush.Style:=bsSolid;
    FillRect(Rect(0,0,PenColorBox.Width,PenColorBox.Height));
  end;
end;

procedure TMainForm.BrushColorBoxPaint(Sender: TObject);
begin
  with BrushColorBox.Canvas do begin
    Brush.Color:=BrushColorBox.Color;
    Brush.Style:=bsSolid;
    FillRect(Rect(0,0,BrushColorBox.Width,BrushColorBox.Height));
  end;
end;

procedure TMainForm.PenStyleComboClick(Sender: TObject);
begin
  if (SelectButton.Down and (Plan.ActiveObject<>nil)) then with Plan.ActiveObject do begin
    Pen.Style:=TPenStyle(PenStyleCombo.ItemIndex);
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.PenWidthEditChange(Sender: TObject);
begin
  if not SelectButton.Down then Exit;
  Plan.Pen.Width := PenWidthEdit.AsInteger;
  if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
    Pen.Width := Plan.Pen.Width;
    NeedRepaint;
  end;
  PenStyleCombo.Repaint;
  PlanSaved := False;
end;

procedure TMainForm.BrushStyleComboClick(Sender: TObject);
begin
  if not SelectButton.Down then Exit;
  Plan.Brush.Style := TBrushStyle(BrushStyleCombo.ItemIndex);
  if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
    Brush.Style := Plan.Brush.Style;
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.ScaleXEditChange(Sender: TObject);
begin
  Plan.ScaleX := ScaleXEdit.AsInteger;
  Plan.Repaint;
  PlanSaved := False;
end;

procedure TMainForm.ScaleYEditChange(Sender: TObject);
begin
  Plan.ScaleY := ScaleYEdit.AsInteger;
  Plan.Repaint;
  PlanSaved := False;
end;

procedure TMainForm.PlanNewItemClick(Sender: TObject);
begin
  FPlanFileName:='';
  Caption:=FAppTitle;
  Plan.Clear;
  PropertiesPanel.Visible:=False;
  Plan.Repaint;
  UpdateLayersList;
end;

procedure TMainForm.PlanOpenItemClick(Sender: TObject);
begin
  if not PlanSaved then case MessageDlg(sPlanSaveWarning,mtConfirmation,mbYesNoCancel,0) of
    mrYes    : PlanSaveItemClick(Self);
    mrCancel : Exit;
  end;
  if PlanOpenDialog.Execute then OpenPlan(PlanOpenDialog.FileName);
end;

procedure TMainForm.PlanSaveItemClick(Sender: TObject);
begin
  if (FPlanFileName='') then PlanSaveAsItemClick(Self) else Plan.SaveToFile(FPlanFileName);
  PlanSaved := True;
end;

procedure TMainForm.PlanSaveAsItemClick(Sender: TObject);
begin
  if PlanSaveDialog.Execute then begin
    FPlanFileName := PlanSaveDialog.FileName;
    PlanMRUManager.Add(FPlanFileName,0);
    Plan.SaveToFile(FPlanFileName);
    Caption:=FPlanFileName+' - '+FAppTitle;
    PlanSaved := True;
  end;
end;

procedure TMainForm.ScaleZoomItemClick(Sender: TObject);
begin
  with Plan do begin
    Width:=Trunc(Width*1.2);
    Height:=Trunc(Height*1.2);
  end;
  ScaleUnzoomItem.Enabled:=True;
  ZoomOutButton.Enabled:=ScaleUnzoomItem.Enabled;
end;

procedure TMainForm.ScaleUnzoomItemClick(Sender: TObject);
begin
  with Plan do begin
    if (Width<100) or (Height<100) then begin
      ScaleUnzoomItem.Enabled:=False;
      ZoomOutButton.Enabled:=ScaleUnzoomItem.Enabled;
      Exit;
    end;
    Width:=Trunc(Width*0.8);
    Height:=Trunc(Height*0.8);
  end;
end;

procedure TMainForm.LayersListBoxClick(Sender: TObject);
begin
  if (LayersListBox.ItemIndex < 0) then Exit;
  Plan.CurrentLayer:=Plan.Layers[LayersListBox.ItemIndex];
  LayerReadOnlyCheck.Checked:=Plan.CurrentLayer.ReadOnly;
  RefreshButtons;
end;

procedure TMainForm.LayersListBoxClickCheck(Sender: TObject);
begin
  Plan.Layers[LayersListBox.ItemIndex].Visible:=LayersListBox.Checked[LayersListBox.ItemIndex];
end;

procedure TMainForm.PlanEditorSpeedBarResize(Sender: TObject);
begin
  ExitButton.Left:=PlanEditorSpeedBar.Width-PlanEditorSpeedBar.BtnWidth-5;
end;

procedure TMainForm.PenColorBoxDblClick(Sender: TObject);
begin
  if (SelectButton.Down and ColorDialog.Execute) then begin
    Plan.Pen.Color := ColorDialog.Color;
    PenColorBox.Color := ColorDialog.Color;
    PenColorBox.Repaint;
    if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
      Pen.Color := ColorDialog.Color;
      NeedRepaint;
    end;
  end;
end;

procedure TMainForm.BrushColorBoxDblClick(Sender: TObject);
begin
  if (SelectButton.Down and ColorDialog.Execute) then begin
    Plan.Brush.Color := ColorDialog.Color;
    BrushColorBox.Color := ColorDialog.Color;
    BrushColorBox.Repaint;
    BrushStyleCombo.Repaint;
    if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
      Brush.Color := ColorDialog.Color;
      NeedRepaint;
    end;  
  end;
end;

procedure TMainForm.PlanObjectClick(Plan: TOxygenPlan; PlanObject: TPlanObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  var i,k : Integer;
      s   : String;
      po  : TPlanObject;
begin
  if (PlanObject = nil) then Exit;
  PlanSaved := False;
  PropertiesPanel.Visible := True;
  FUpdatingData := True;
  ObjectNameEdit.Text := PlanObject.Name;
  ObjectIDEdit.Value := PlanObject.ID;
  ObjectReadOnlyCheck.Checked := PlanObject.ReadOnly;
  ObjectLayerCombo.ItemIndex:=ObjectLayerCombo.Items.IndexOf(PlanObject.Layer.Name);
  ObjectChildrenGroupBox.Caption := sChildObjects + IntToStr(PlanObject.ChildrenCount);
  ObjectChildrenCombo.Items.Clear;
  for i:=1 to PlanObject.ChildrenCount do begin
    po:=PlanObject.Objects[i-1];
    ObjectChildrenCombo.Items.AddObject(po.ObjectTypeDescr+': '+po.Name+' (ID: '+IntToStr(po.ID)+')',po);
  end;
  with ObjectChildrenCombo do if (Items.Count>0) then begin
    Enabled:=True;
    ItemIndex:=0
  end
  else Enabled:=False;
  ObjectChildSelectButton.Enabled:=ObjectChildrenCombo.Enabled;
  PenColorBox.Color:=PlanObject.Pen.Color;
  BrushColorBox.Color:=PlanObject.Brush.Color;
  PenStyleCombo.ItemIndex:=Integer(PlanObject.Pen.Style);
  PenWidthEdit.Value:=PlanObject.Pen.Width;
  if (PlanObject.Brush.Bitmap<>nil) then begin
    if (Plan.Brush.Bitmap<>nil) then try Plan.Brush.Bitmap.Free  except end;
    Plan.Brush.Bitmap:=PlanObject.Brush.Bitmap;
    BrushStyleCombo.ItemIndex:=8;
  end
  else BrushStyleCombo.ItemIndex:=Integer(PlanObject.Brush.Style);
  PenColorBox.Repaint;
  BrushColorBox.Repaint;
  PenStyleCombo.Repaint;
  BrushStyleCombo.Repaint;
  ObjectUnselectColorItem.Enabled := PlanObject.SelectedByColor;
  with ObjectParentLabel do if (PlanObject.Parent = nil) then begin
    Caption := '<Has no parent>';
    Font.Color := clGray;
    Font.Style := Font.Style - [fsUnderline];
    Cursor := crDefault;
  end
  else begin
    Caption := PlanObject.Parent.Name + ' :' + PlanObject.Parent.ObjectTypeDescr;
    Font.Color := clBlue;
    Font.Style := Font.Style + [fsUnderline];
    Cursor := crHandPoint;
  end;
  GradientActiveCheck.Checked := PlanObject.GradientRecord.Active;
  GradientColorsEdit.AsInteger := PlanObject.GradientRecord.Colors;
  GradientStartColorPanel.Color := PlanObject.GradientRecord.StartColor;
  GradientEndColorPanel.Color := PlanObject.GradientRecord.EndColor;
  GradientDirectionCombo.ItemIndex := Integer(PlanObject.GradientRecord.Direction);

  if (PlanObject is TPlanLine) then with (PlanObject as TPlanLine) do begin
    CurObjectPanel.Caption := sLine;
    PropertiesNotebook.PageIndex:=0;
    LineX1Edit.Value:=X1;
    LineY1Edit.Value:=Y1;
    LineX2Edit.Value:=X2;
    LineY2Edit.Value:=Y2;
  end
  else if (PlanObject is TPlanTraceLine) then with (PlanObject as TPlanTraceLine) do begin
    CurObjectPanel.Caption := sTraceLine;
    PropertiesNotebook.PageIndex := 5;
  end
  else if (PlanObject is TPlanPolyLine) then with (PlanObject as TPlanPolyLine) do begin
    CurObjectPanel.Caption := sPolyLine;
    PropertiesNotebook.PageIndex := 5;
  end
  else if (PlanObject is TPlanPolygon) then with (PlanObject as TPlanPolygon) do begin
    CurObjectPanel.Caption := sPolygon;
    PropertiesNotebook.PageIndex:=5;
  end
  else if (PlanObject is TPlanAniPicture) then with (PlanObject as TPlanAniPicture) do begin
    CurObjectPanel.Caption := sAniPicture;
    PropertiesNotebook.PageIndex:=6;
    AniPictureX1Edit.Value:=X1;
    AniPictureY1Edit.Value:=Y1;
    AniPictureX2Edit.Value:=X2;
    AniPictureY2Edit.Value:=Y2;
    AniPictureFramesEdit.Value := ImageCount;
    AniPictureFrameEdit.Enabled := not Blinking;
    AniPictureFrameEdit.MaxValue := ImageCount - 1;
    AniPictureFrameEdit.Value := ImageIndex;
    if (StdPictureName <> '') then try StdAniPictureCombo.ItemIndex := StdAniPictureCombo.Items.IndexOf(StdPictureName) except StdAniPictureCombo.ItemIndex := 0 end
                              else StdAniPictureCombo.ItemIndex := 0;
  end
  else if (PlanObject is TPlanAniGif) then with (PlanObject as TPlanAniGif) do begin
    CurObjectPanel.Caption := sAniGif;
    PropertiesNotebook.PageIndex:=7;
    AniGifX1Edit.Value:=X1;
    AniGifY1Edit.Value:=Y1;
    AniGifX2Edit.Value:=X2;
    AniGifY2Edit.Value:=Y2;
    AniGifFramesPanel.Caption := IntToStr(FrameCount);
    AniGifFrameEdit.Value := FrameIndex;
    AniGifFrameEdit.MaxValue := FrameCount - 1;
    AniGifFrameEdit.Enabled := not Blinking;
    if (StdAniGifName <> '') then try StdAniGifCombo.ItemIndex := StdAniGifCombo.Items.IndexOf(StdAniGifName) except StdAniGifCombo.ItemIndex := 0 end
                             else StdAniGifCombo.ItemIndex := 0;
  end
  else if (PlanObject is TPlanCircle) then with (PlanObject as TPlanCircle) do begin
    CurObjectPanel.Caption := sCircle;
    PropertiesNotebook.PageIndex:=2;
    CircleXEdit.Value:=X;
    CircleYEdit.Value:=Y;
    CircleRadiusEdit.Value:=Radius;
  end
  else if (PlanObject is TPlanText) then with (PlanObject as TPlanText) do begin
    CurObjectPanel.Caption := sText;
    PropertiesNotebook.PageIndex:=3;
    TextX1Edit.Value:=X1;
    TextY1Edit.Value:=Y1;
    TextX2Edit.Value:=X2;
    TextY2Edit.Value:=Y2;
    TextEscapementEdit.Value := Escapement;
    TextEdit.Text:=Text;
    FontCombo.FontName := Font.Name;
    FontSizeEdit.Value := Font.Size;
    FontBoldButton.Down := (fsBold in Font.Style);
    FontItalicButton.Down := (fsItalic in Font.Style);
    FontUnderlineButton.Down := (fsUnderline in Font.Style);
    TextAlignmentCombo.ItemIndex := Integer(Alignment);
    FontColorPanel.Color := Font.Color;
    TextBorderCheck.Checked := (Pen.Mode = pmCopy);
    if (ReadOnly and (Button = mbLeft)) then begin
      i := Pos(':',Text);
      if (i > 0) then begin
        s := UpperCase(System.Copy(Text,1,i-1));
        if (s = 'HTTP') or (s = 'FTP') or (s = 'MAILTO') then ShellExecute(0,'open',PChar(Text),nil,nil,SW_SHOWNORMAL);
      end;
    end;
  end
  else if (PlanObject is TPlanPicture) then with (PlanObject as TPlanPicture) do begin
    CurObjectPanel.Caption := sPicture;
    PropertiesNotebook.PageIndex:=4;
    PictureX1Edit.Value:=X1;
    PictureY1Edit.Value:=Y1;
    PictureX2Edit.Value:=X2;
    PictureY2Edit.Value:=Y2;
    PictureTransparentCheck.Visible := (Picture.Graphic <> nil);
    if PictureTransparentCheck.Visible then PictureTransparentCheck.Checked := {Picture.Graphic.}Transparent;
    if (StdPictureName <> '') then try StdPictureCombo.ItemIndex := StdPictureCombo.Items.IndexOf(StdPictureName) except StdPictureCombo.ItemIndex := 0 end
                              else StdPictureCombo.ItemIndex := 0;
  end
  else if (PlanObject is TPlanBox) then with (PlanObject as TPlanBox) do begin
    CurObjectPanel.Caption := sRectangle;
    PropertiesNotebook.PageIndex:=1;
    BoxX1Edit.Value:=X1;
    BoxY1Edit.Value:=Y1;
    BoxX2Edit.Value:=X2;
    BoxY2Edit.Value:=Y2;
  end;
  Application.ProcessMessages;
  ObjectStopBlinkItem.Enabled := PlanObject.Blinking;
  ObjectStartBlinkItem.Enabled := not ObjectStopBlinkItem.Enabled;
  if ObjectStopBlinkItem.Enabled then begin
    StartStopAnimateButton.ImageIndex:=1;
    StartStopAnimateButton.Hint := sStopAnimating;
  end
  else begin
    StartStopAnimateButton.ImageIndex:=0;
    StartStopAnimateButton.Hint := sStartAnimating;
  end;

  k:=1;
  with ObjectPropertiesGrid do begin
    RowCount := PlanObject.Properties.Count+1;
    Cells[0,1]:='';
    Cells[1,1]:='';
    for i:=1 to PlanObject.Properties.Count do begin
      s := Trim(PlanObject.Properties.Names[i-1]);
      if not PlanObject.HasInternalProperty(s) then begin
        Cells[0,k]:=s;
        Cells[1,k]:=PlanObject.Properties.Values[s];
        Inc(k);
      end;
    end;
    if (k>1) then RowCount:=k else RowCount:=2;
  end;
  FUpdatingData:=False;
  RefreshButtons;
end;

procedure TMainForm.FontComboClick(Sender: TObject);
begin
  Plan.Font.Name:=FontCombo.FontName;
  if (SelectButton.Down and (Plan.ActiveObject<>nil) and (Plan.ActiveObject is TPlanText)) then with (Plan.ActiveObject as TPlanText) do begin
    Font.Name:=Plan.Font.Name;
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.FontSizeEditChange(Sender: TObject);
begin
  Plan.Font.Size:=Trunc(FontSizeEdit.Value);
  if (SelectButton.Down and (Plan.ActiveObject<>nil) and (Plan.ActiveObject is TPlanText)) then with (Plan.ActiveObject as TPlanText) do begin
    Font.Size:=Plan.Font.Size;
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.FontBoldButtonClick(Sender: TObject);
begin
  with Plan.Font do begin
    if FontBoldButton.Down then Style:=Style+[fsBold] else Style:=Style-[fsBold];
    if FontItalicButton.Down then Style:=Style+[fsItalic] else Style:=Style-[fsItalic];
    if FontUnderlineButton.Down then Style:=Style+[fsUnderline] else Style:=Style-[fsUnderline];
  end;
  if (SelectButton.Down and (Plan.ActiveObject<>nil) and (Plan.ActiveObject is TPlanText)) then with (Plan.ActiveObject as TPlanText) do begin
    Font.Style:=Plan.Font.Style;
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.ObjectSavePropertiesItemClick(Sender: TObject);
  var PlanObject:TPlanObject;
      i : Integer;
      s : String;
begin
  PlanObject:=Plan.ActiveObject;
  if (PlanObject=nil) then Exit;
  PlanObject.Name:=Trim(ObjectNameEdit.Text);
  PlanObject.ID:=Trunc(ObjectIDEdit.Value);

  with ObjectPropertiesGrid do for i:=1 to RowCount-1 do begin
    s := Trim(Cells[0,i]);
    if (s<>'') then if not PlanObject.HasInternalProperty(UpperCase(s)) then PlanObject.Properties.Values[s] := Trim(Cells[1,i]);
  end;
  PlanSaved := False;
end;

procedure TMainForm.LineX1EditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanLine) then with (PlanObject as TPlanLine) do begin
    X1:=Trunc(LineX1Edit.Value);
    Y1:=Trunc(LineY1Edit.Value);
    X2:=Trunc(LineX2Edit.Value);
    Y2:=Trunc(LineY2Edit.Value);
  end;
  PlanSaved := False;
end;

procedure TMainForm.BoxX1EditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanBox) then with (PlanObject as TPlanBox) do begin
    X1:=Trunc(BoxX1Edit.Value);
    Y1:=Trunc(BoxY1Edit.Value);
    X2:=Trunc(BoxX2Edit.Value);
    Y2:=Trunc(BoxY2Edit.Value);
  end;
  PlanSaved := False;
end;

procedure TMainForm.CircleXEditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanCircle) then with (PlanObject as TPlanCircle) do begin
    X:=Trunc(CircleXEdit.Value);
    Y:=Trunc(CircleYEdit.Value);
    Radius:=Trunc(CircleRadiusEdit.Value);
  end;
  PlanSaved := False;
end;

procedure TMainForm.TextX1EditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanText) then with (PlanObject as TPlanText) do begin
    X1 := TextX1Edit.AsInteger;
    Y1 := TextY1Edit.AsInteger;
    X2 := TextX2Edit.AsInteger;
    Y2 := TextY2Edit.AsInteger;
    Escapement := TextEscapementEdit.AsInteger;
  end;
  PlanSaved := False;
end;

procedure TMainForm.TextEditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanText) then with (PlanObject as TPlanText) do Text:=Trim(TextEdit.Text);
  PlanSaved := False;
end;

procedure TMainForm.TextAlignmentComboClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanText) then with (PlanObject as TPlanText) do Alignment:=TAlignment(TextAlignmentCombo.ItemIndex);
  PlanSaved := False;
end;

procedure TMainForm.PictureX1EditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanPicture) then with (PlanObject as TPlanPicture) do begin
    X1:=Trunc(PictureX1Edit.Value);
    Y1:=Trunc(PictureY1Edit.Value);
    X2:=Trunc(PictureX2Edit.Value);
    Y2:=Trunc(PictureY2Edit.Value);
  end;
  PlanSaved := False;
end;

procedure TMainForm.SelectPictureButtonClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (PlanObject=nil) then Exit;
  if (PlanObject is TPlanPicture) then with (PlanObject as TPlanPicture) do if SelectPictureDialog.Execute then begin
    Picture.LoadFromFile(SelectPictureDialog.FileName);
    StdPictureCombo.ItemIndex := 0;
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.LayerAddItemClick(Sender: TObject);
  label m1;
  var s:String;
      i:Integer;
begin
  i:=Plan.Layers[Plan.Layers.Count-1].Index+1;
  while (Plan.Layers.LayerByName(sLayer+IntToStr(i))<>nil) do Inc(i);
  s:=sLayer+IntToStr(i);
m1:
  if not InputQuery(sAddLayerCaption,sAddLayerPrompt,s) then Exit;
  if (Plan.Layers.LayerByName(s)<>nil) then if (MessageDlg(Format(sLayerNameExists,[s]),mtWarning,mbYesNoCancel,0)=mrYes) then goto m1 else Exit;
  s:=Trim(s);
  if (s='') then if (MessageDlg(sLayerNameEmpty,mtWarning,mbYesNoCancel,0)=mrYes) then goto m1 else Exit;
  i:=Plan.Layers.Add(s);
  Plan.CurrentLayer:=Plan.Layers[i];
  UpdateLayersList;
  Plan.Repaint;
  PlanSaved := False;
end;

procedure TMainForm.LayerDeleteItemClick(Sender: TObject);
  var s:String;
      i:Integer;
begin
  if (Plan.Layers.Count <= 1) then Exit;
  s:=Plan.CurrentLayer.Name;
  i := Plan.CurrentLayer.Count;
  if (i > 0) then s := Format(sRemoveLayerHasChildren,[s,i,s]) else s := Format(sRemoveLayer,[s]);
  if (MessageDlg(s,mtConfirmation,mbYesNoCancel,0) <> mrYes) then Exit;
  i:=Plan.Layers.IndexOf(Plan.CurrentLayer.Name);
  if (i = -1) then Exit;
  if (i > 0) then Plan.CurrentLayer:=Plan.Layers[i-1] else Plan.CurrentLayer:=Plan.Layers[i+1];
  Plan.Layers.Delete(i);
  UpdateLayersList;
  RefreshButtons;
  Plan.Repaint;
  PlanSaved := False;
end;

procedure TMainForm.LayerRenameItemClick(Sender: TObject);
  var s:String;
begin
  s:=Plan.CurrentLayer.Name;
  if not InputQuery(sRenameLayerCaption,sRenameLayerPrompt,s) then Exit;
  s:=Trim(s);
  if (s<>'') then try
    Plan.CurrentLayer.Name:=s;
    LayersListBox.Items[LayersListBox.ItemIndex]:=s;
  except end;
  PlanSaved := False;
end;


procedure TMainForm.ObjectAddPropertyItemClick(Sender: TObject);
  label m1;
  var s,sv:String;
      po:TPlanObject;
      i:Integer;
begin
  po:=Plan.ActiveObject;
  if (po=nil) then Exit;
  s:='';
m1:
  if not InputQuery(sPropertyAddCaption,sPropertyAddPrompt,s) then Exit;
  s := Trim(s);
  if (s = '') then begin
    MessageDlg(sPropertyNameIsEmpty,mtError,[mbOk],0);
    Exit;
  end;
  if (s[1]<>'$') then s := '$' + s; // to prevent conflicts with standard properties
  for i:=1 to po.Properties.Count do if (AnsiUpperCase(po.Properties.Names[i-1]) = AnsiUpperCase(s)) then begin
    MessageDlg(sPropertyAlreadyExists,mtInformation,[mbOk],0);
    goto m1;
  end;
  sv:='';
  InputQuery(sAddPropertyValueCaption,Format(sAddPropertyValuePrompt,[s]),sv);
  po.Properties.Values[s]:=sv;
  with ObjectPropertiesGrid do begin
    if (Trim(Cells[0,1])<>'') then RowCount:=RowCount+1;
    Cells[0,RowCount-1]:=s;
    Cells[1,RowCount-1]:=sv;
  end;
  PlanSaved := False;
end;

procedure TMainForm.ObjectDeleteItemClick(Sender: TObject);
  var po:TPlanObject;
begin
  po:=Plan.ActiveObject;
  if (po=nil) then Exit;
  if (MessageDlg(Format(sRemoveCurrentObject,[po.Name,po.ObjectTypeDescr]),mtConfirmation,mbYesNoCancel,0)<>mrYes) then Exit;
  po.Free;
  PlanSaved := False;
  RefreshButtons;
end;

procedure TMainForm.SelectButtonClick(Sender: TObject);
begin
  Plan.CancelDrawNewObject;
end;

procedure TMainForm.DrawLineButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanLine);
end;

procedure TMainForm.DrawBoxButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanBox);
end;

procedure TMainForm.DrawCircleButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanCircle);
end;

procedure TMainForm.DrawEllipseButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanEllipse);
end;

procedure TMainForm.DrawTextButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanText);
end;

procedure TMainForm.DrawPictureButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanPicture);
end;

procedure TMainForm.DrawPolygonButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanPolygon);
end;

procedure TMainForm.DrawPolyLineButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanPolyline);
end;

procedure TMainForm.DrawTraceLineButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanTraceline);
end;

procedure TMainForm.DrawAniPictureButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanAniPicture);
end;

procedure TMainForm.DrawAniGifButtonClick(Sender: TObject);
begin
  Plan.DrawNewObject(TPlanAniGif);
end;

procedure TMainForm.PlanAfterDrawNewObject(Plan: TOxygenPlan; PlanObject: TPlanObject);
  var s:String;
begin
  PlanSaved := False;
  if (PlanObject is TPlanText) then begin
    s:='';
    InputQuery(sAddTextCaption,sAddTextPrompt,s);
    (PlanObject as TPlanText).Text:=s;
  end
  else if (PlanObject is TPlanAniPicture) then begin
    if SelectAniPictureDialog.Execute then with (PlanObject as TPlanAniPicture) do begin
      Picture.LoadFromFile(SelectAniPictureDialog.FileName);
      ImageCount := 2;
      NeedRepaint;
    end;  
  end
  else if (PlanObject is TPlanAniGif) then begin
    if SelectAniGifDialog.Execute then (PlanObject as TPlanAniGif).GIFImage.LoadFromFile(SelectAniGifDialog.FileName);
    PlanObject.NeedRepaint;
  end
  else if (PlanObject is TPlanPicture) then begin
    if SelectPictureDialog.Execute then (PlanObject as TPlanPicture).Picture.LoadFromFile(SelectPictureDialog.FileName);
    PlanObject.NeedRepaint;
  end;
  SelectButton.Down:=True;
  RefreshButtons;
end;

procedure TMainForm.Scale100ItemClick(Sender: TObject);
begin
  with Plan do begin
    Height:=ScaleY;
    Width:=ScaleX;
  end;
end;

procedure TMainForm.AniPictureX1EditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanAniPicture) then with (PlanObject as TPlanAniPicture) do begin
    X1:=Trunc(AniPictureX1Edit.Value);
    Y1:=Trunc(AniPictureY1Edit.Value);
    X2:=Trunc(AniPictureX2Edit.Value);
    Y2:=Trunc(AniPictureY2Edit.Value);
  end;
  PlanSaved := False;
end;

procedure TMainForm.AniPictureFramesEditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanAniPicture) then with (PlanObject as TPlanAniPicture) do begin
    ImageCount:=AniPictureFramesEdit.AsInteger;
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.AniPictureFrameEditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil) or PlanObject.Blinking) then Exit;
  if (PlanObject is TPlanAniPicture) then (PlanObject as TPlanAniPicture).ImageIndex := AniPictureFrameEdit.AsInteger;
  PlanSaved := False;
end;

procedure TMainForm.SelectAniPictureButtonClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (PlanObject=nil) then Exit;
  if (PlanObject is TPlanAniPicture) then with (PlanObject as TPlanAniPicture) do if SelectAniPictureDialog.Execute then begin
    Picture.LoadFromFile(SelectAniPictureDialog.FileName);
    StdAniPictureCombo.ItemIndex := 0;
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.AniGifX1EditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (FUpdatingData or (PlanObject=nil)) then Exit;
  if (PlanObject is TPlanAniGif) then with (PlanObject as TPlanAniGif) do begin
    X1:=Trunc(AniGifX1Edit.Value);
    Y1:=Trunc(AniGifY1Edit.Value);
    X2:=Trunc(AniGifX2Edit.Value);
    Y2:=Trunc(AniGifY2Edit.Value);
  end;
  PlanSaved := False;
end;

procedure TMainForm.AniGifFrameEditChange(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject := Plan.ActiveObject;
  if (FUpdatingData or (PlanObject = nil) or PlanObject.Blinking) then Exit;
  if (PlanObject is TPlanAniGif) then (PlanObject as TPlanAniGif).FrameIndex := AniGifFrameEdit.AsInteger;
  PlanSaved := False;
end;

procedure TMainForm.SelectAniGifButtonClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject:=Plan.ActiveObject;
  if (PlanObject=nil) then Exit;
  if (PlanObject is TPlanAniGif) then with (PlanObject as TPlanAniGif) do if SelectAniGifDialog.Execute then begin
    GIFImage.LoadFromFile(SelectAniGifDialog.FileName);
    StdAniGifCombo.ItemIndex := 0;
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.PlanObjectMouseMove(Plan: TOxygenPlan; PlanObject: TPlanObject);
  //var i : Integer;
begin
  if (PlanObject <> nil) then begin
    {if (PlanObject is TPlanText) then if PlanObject.ReadOnly then begin
      i := Pos('://',(PlanObject as TPlanText).Text);
      if (i = 4) or (i = 5) then
        Plan.Cursor := crHandPoint
        else Plan.Cursor := crDefault;
    end;}
    with PlanObject do StatusPanel.Caption:=Name+' :'+ObjectTypeDescr;
  end
  else StatusPanel.Caption:='';
end;

procedure TMainForm.StartStopAnimateButtonClick(Sender: TObject);
  var po:TPlanObject;
      intv : Integer;
      si : String;
begin
  po:=Plan.ActiveObject;
  if (po = nil) then Exit;
  if po.Blinking then begin
    po.StopBlink;
    StartStopAnimateButton.ImageIndex:=0;
    StartStopAnimateButton.Hint := sStartAnimating;
    ObjectStartBlinkItem.Enabled := True;
    ObjectStopBlinkItem.Enabled := False;
    Exit;
  end;
  si := '500';
  intv := 500;
  if (po is TPlanAniPicture) then si := IntToStr((po as TPlanAniPicture).Interval);
  if not (po is TPlanAniGif) then if not InputQuery(sPeriodCaption,sPeriodPrompt,si) then Exit;
  try intv := StrToInt(si) except end;

  if not ((po is TPlanAniGif) or (po is TPlanAniPicture)) then begin
    Application.CreateForm(TBlinkParamsForm,BlinkParamsForm);
    if (po is TPlanPicture) then begin
      with BlinkParamsForm.BlinkTypeCombo.Items do begin
        Add('Picture');
      end;
      BlinkParamsForm.BlinkImage.Picture.Assign((po as TPlanPicture).BlinkPicture);
      if (BlinkParamsForm.ShowModal <> mrOk) then begin
        BlinkParamsForm.Free;
        Exit
      end;
      po.BlinkType := btPicture;
      (po as TPlanPicture).BlinkPicture.Assign(BlinkParamsForm.BlinkImage.Picture);
    end
    else begin
      with BlinkParamsForm do begin
        with BlinkTypeCombo.Items do begin
          Add('Pen');
          Add('Brush');
        end;
        PenColorPanel.Color := po.BlinkPen.Color;
        PenWidthEdit.AsInteger := po.BlinkPen.Width;
        PenStyleCombo.ItemIndex := Integer(po.BlinkPen.Style);
        BrushColorPanel.Color := po.BlinkBrush.Color;
        BrushStyleCombo.ItemIndex := Integer(po.BlinkBrush.Style);
        if (po is TPlanText) then begin
          with BlinkTypeCombo.Items do begin
            Add('Font');
            Add('Text');
          end;
          TextEdit.Text := (po as TPlanText).BlinkText;
          FontPanel.Font.Assign((po as TPlanText).BlinkFont);
        end;
        if (ShowModal <> mrOk) then begin
          Free;
          Exit
        end;
        si := BlinkTypeCombo.Items[BlinkTypeCombo.ItemIndex];
        if (si = 'Pen') then begin
          po.BlinkType := btPen;
          po.BlinkPen.Color := PenColorPanel.Color;
          po.BlinkPen.Width := PenWidthEdit.AsInteger;
          po.BlinkPen.Style := TPenStyle(PenStyleCombo.ItemIndex);
        end
        else if (si = 'Brush') then begin
          po.BlinkType := btBrush;
          po.BlinkBrush.Color := BrushColorPanel.Color;
          po.BlinkBrush.Style := TBrushStyle(BrushStyleCombo.ItemIndex);
        end
        else if (si = 'Font') then begin
          po.BlinkType := btFont;
          (po as TPlanText).BlinkFont.Assign(FontPanel.Font);
        end
        else if (si = 'Text') then begin
          po.BlinkType := btText;
          (po as TPlanText).BlinkText := TextEdit.Text;
        end;
      end;
    end;
    BlinkParamsForm.Free;
  end;
  po.StartBlink(intv);
  StartStopAnimateButton.ImageIndex:=1;
  StartStopAnimateButton.Hint := sStopAnimating;
  ObjectStartBlinkItem.Enabled := False;
  ObjectStopBlinkItem.Enabled := True;
end;

procedure TMainForm.BackgroundPictureSelectItemClick(Sender: TObject);
begin
  if SelectPictureDialog.Execute then begin
    Plan.BackgroundPicture.LoadFromFile(SelectPictureDialog.FileName);
    Plan.Repaint;
    RefreshButtons;
    PlanSaved := False;
  end;
end;

procedure TMainForm.BackgroundPictrureRemoveItemClick(Sender: TObject);
begin
  Plan.BackgroundPicture:=nil;
  RefreshButtons;
  PlanSaved := False;
end;

procedure TMainForm.ObjectLayerComboClick(Sender: TObject);
  var po : TPlanObject;
      l : TPlanLayer;
begin
  po := Plan.ActiveObject;
  if (po = nil) then Exit;
  try
    l := Plan.Layers.LayerByName(ObjectLayerCombo.Items[ObjectLayerCombo.ItemIndex]);
    po.Layer := l;
  except end;
  PlanSaved := False;
end;

procedure TMainForm.LayerReadOnlyCheckClick(Sender: TObject);
begin
  Plan.CurrentLayer.ReadOnly := LayerReadOnlyCheck.Checked;
end;

procedure TMainForm.StandardPicturesItemClick(Sender: TObject);
  var f : Boolean;
begin
  Application.CreateForm(TStandardPicturesForm,StandardPicturesForm);
  with StandardPicturesForm do begin
    FPlan := Self.Plan;
    ShowModal;
    f := FWasChanges;
    Free;
  end;
  if f then begin
    RefreshStdImages;
    if (Plan.ActiveObject <> nil) then PlanObjectClick(Plan,Plan.ActiveObject,mbLeft,[],0,0);
  end;
end;

procedure TMainForm.StandardAniGifsItemClick(Sender: TObject);
  var f : Boolean;
begin
  Application.CreateForm(TStandardAniGifsForm,StandardAniGifsForm);
  with StandardAniGifsForm do begin
    FPlan := Self.Plan;
    ShowModal;
    f := FWasChanges;
    Free;
  end;
  if f then begin
    RefreshStdImages;
    if (Plan.ActiveObject <> nil) then PlanObjectClick(Plan,Plan.ActiveObject,mbLeft,[],0,0);
  end;
end;

procedure TMainForm.StdPictureComboClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  if (StdPictureCombo.ItemIndex = 0) then Exit;
  PlanObject:=Plan.ActiveObject;
  if (PlanObject=nil) then Exit;
  if (PlanObject is TPlanPicture) then with (PlanObject as TPlanPicture) do begin
    StdPictureName := StdPictureCombo.Items[StdPictureCombo.ItemIndex];
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.StdAniPictureComboClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  if (StdAniPictureCombo.ItemIndex = 0) then Exit;
  PlanObject:=Plan.ActiveObject;
  if (PlanObject=nil) then Exit;
  if (PlanObject is TPlanAniPicture) then with (PlanObject as TPlanAniPicture) do begin
    StdPictureName := StdAniPictureCombo.Items[StdAniPictureCombo.ItemIndex];
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.StdAniGifComboClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  if (StdAniGifCombo.ItemIndex = 0) then Exit;
  PlanObject:=Plan.ActiveObject;
  if (PlanObject=nil) then Exit;
  if (PlanObject is TPlanAniGif) then with (PlanObject as TPlanAniGif) do begin
    StdAniGifName := StdAniGifCombo.Items[StdAniGifCombo.ItemIndex];
    NeedRepaint;
  end;
  PlanSaved := False;
end;

procedure TMainForm.ObjectChildSelectButtonClick(Sender: TObject);
  var po : TPlanObject;
begin
  if ((ObjectChildrenCombo.Items.Count = 0) or (ObjectChildrenCombo.ItemIndex < 0)) then Exit;
  po := TPlanObject(ObjectChildrenCombo.Items.Objects[ObjectChildrenCombo.ItemIndex]);
  if (po <> nil) then try
    if (Plan.ActiveObject <> nil) then Plan.ActiveObject.UnSelect;
    po.Select;
    PlanObjectClick(Plan,po,mbLeft,[],0,0);
  except end;
end;

procedure TMainForm.ObjectReadOnlyCheckClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject := Plan.ActiveObject;
  if (PlanObject = nil) then Exit;
  PlanObject.ReadOnly := ObjectReadOnlyCheck.Checked;
end;

procedure TMainForm.PictureTransparentCheckClick(Sender: TObject);
  var PlanObject:TPlanObject;
begin
  PlanObject := Plan.ActiveObject;
  if (FUpdatingData or (PlanObject = nil)) then Exit;
  if (PlanObject is TPlanPicture) then with (PlanObject as TPlanPicture) do if (Picture.Graphic <> nil) then begin
    {Picture.Graphic.}Transparent := PictureTransparentCheck.Checked;
    NeedRepaint;
  end;
  PlanSaved := False;  
end;

procedure TMainForm.FormatFontItemClick(Sender: TObject);
  var po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po <> nil) and (po is TPlanText) then FontSelectDialog.Font := (po as TPlanText).Font else FontSelectDialog.Font := Plan.Font;
  with FontSelectDialog do if Execute then begin
    Plan.Font := Font;
    FontCombo.FontName := Font.Name;
    FontSizeEdit.Value := Font.Size;
    FontBoldButton.Down := (fsBold in Font.Style);
    FontItalicButton.Down := (fsItalic in Font.Style);
    FontUnderlineButton.Down := (fsUnderline in Font.Style);
    if (SelectButton.Down and (po <> nil) and (po is TPlanText)) then (po as TPlanText).Font := Font;
  end;
  PlanSaved := False;
end;

procedure TMainForm.BackgroundColorItemClick(Sender: TObject);
begin
  ColorSelectDialog.Color := Plan.Brush.Color;
  if ColorSelectDialog.Execute then begin
    Plan.Color := ColorSelectDialog.Color;
    Plan.Repaint;
    PlanSaved := False;
  end;
end;

procedure TMainForm.ObjectDeletePropertyItemClick(Sender: TObject);
  var r,i : Integer;
      s : String;
      po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po = nil) then Exit;
  r := ObjectPropertiesGrid.Row;
  s := ObjectPropertiesGrid.Cells[0,r];
  if (Trim(s) = '') then Exit;
  if (MessageDlg(Format(sRemoveCustomProperty,[s]),mtConfirmation,mbYesNoCancel,0) <> mrYes) then Exit;
  s := UpperCase(s);
  for i := 1 to po.Properties.Count do if (UpperCase(po.Properties.Names[i-1]) = s) then begin
    po.Properties.Delete(i-1);
    PlanObjectClick(Plan,po,mbLeft,[],0,0);
  end;
end;


procedure TMainForm.PlanMRUManagerClick(Sender: TObject; const RecentName, Caption: String; UserData: Integer);
begin
  if not PlanSaved then case MessageDlg(sPlanSaveWarning,mtConfirmation,mbYesNoCancel,0) of
    mrYes    : PlanSaveItemClick(Self);
    mrCancel : Exit;
  end;
  OpenPlan(RecentName);
end;

procedure TMainForm.FindObjectItemClick(Sender: TObject);
  var l : TPlanLayer;
      po : TPlanObject;
      i : Integer;
begin
  if (FindObjectForm.ShowModal <> mrOk) then Exit;
  po := FindObjectForm.FoundObject;
  if (po = nil) then Exit;
  l := po.Layer;
  if (l <> Plan.CurrentLayer) then begin
    i := Plan.Layers.IndexOf(l.Name);
    if (i < 0) then Exit;
    LayersListBox.ItemIndex := i;
    LayersListBoxClick(Self);
  end;
  if (Plan.ActiveObject <> nil) then Plan.ActiveObject.Unselect;
  po.Select;
  PlanObjectClick(Plan,po,mbLeft,[],0,0);
end;

procedure TMainForm.ObjectSelectByColorItemClick(Sender: TObject);
  var po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po = nil) then Exit;
  with ColorSelectDialog do if Execute then begin
    po.SelectByColor(Color);
    ObjectUnselectColorItem.Enabled := True;
    PlanSaved := False;
  end;
end;

procedure TMainForm.ObjectUnselectColorItemClick(Sender: TObject);
  var po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po = nil) or (not po.SelectedByColor) then Exit;
  po.UnselectColor;
  ObjectUnselectColorItem.Enabled := False;
  PlanSaved := False;
end;

procedure TMainForm.ObjectParentLabelClick(Sender: TObject);
  var po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po = nil) or (po.Parent = nil) then Exit;
  if (Plan.ActiveObject <> nil) then Plan.ActiveObject.UnSelect;
  po.Parent.Select;
  PlanObjectClick(Plan,po.Parent,mbLeft,[],0,0);
end;

procedure TMainForm.CloneObjectItemClick(Sender: TObject);
  var po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po = nil) then Exit;
  po.Unselect;
  po := po.Clone(po.Parent);
  po.Select;
  PlanObjectClick(Plan,po,mbLeft,[],0,0);
end;

procedure TMainForm.FontColorPanelClick(Sender: TObject);
  var po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po <> nil) and (po is TPlanText) then ColorSelectDialog.Color := (po as TPlanText).Font.Color else ColorSelectDialog.Color := Plan.Font.Color;
  if ColorSelectDialog.Execute then begin
    Plan.Font.Color := ColorSelectDialog.Color;
    FontColorPanel.Color := ColorSelectDialog.Color;
    if (po <> nil) and (po is TPlanText) then (po as TPlanText).Font.Color := ColorSelectDialog.Color;
    PlanSaved := False;
  end;
end;

procedure TMainForm.PlanParseProgress(Plan: TOxygenPlan; const PercentsCompleted: Integer);
begin
  with ParseProgressBar do begin
    Position := PercentsCompleted;
    Update;
  end;
end;

procedure TMainForm.TextBorderCheckClick(Sender: TObject);
  var po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po = nil) or (not (po is TPlanText)) then Exit;
  with (po as TPlanText) do begin
    if TextBorderCheck.Checked then Pen.Mode := pmCopy else Pen.Mode := pmNop;
    NeedRepaint;
    PlanSaved := False;
  end;
end;

procedure TMainForm.ObjectCopyItemClick(Sender: TObject);
  var sl : TStringList;
      po : TPlanObject;
begin
  po := Plan.ActiveObject;
  if (po = nil) then Exit;
  sl := TStringList.Create;
  try
    po.AddObjectDescr(0,sl);
    Clipboard.SetTextBuf(PChar(sl.Text));
  finally
    sl.Free;
  end;
end;

procedure TMainForm.ObjectPasteItemClick(Sender: TObject);
  var sl : TStringList;
      po,ao : TPlanObject;
      s : String;
begin
  if not Clipboard.HasFormat(CF_TEXT) then Exit;
  ao := Plan.ActiveObject;
  if (ao <> nil) then while (ao <> nil) and (not ao.CanBeParent) do ao := ao.Parent;
  sl := TStringList.Create;
  try
    sl.Text := Clipboard.AsText;
    if (sl.Count > 1) then begin
      //for i:=1 to sl.Count do begin
      s := Trim(sl[0]);
      if (Pos(UpperCase(sStartObject),AnsiUpperCase(s)) = 1) then begin
        sl.Delete(0);
        s := System.Copy(s,Length(sStartObject) + 1, 255);
        po := nil;
        if (AnsiUpperCase(s) = UpperCase(ocLine)) then po := TPlanLine.Create(Plan)
        else if (AnsiUpperCase(s)=UpperCase(ocBox)) then po := TPlanBox.Create(Plan)
        else if (AnsiUpperCase(s)=UpperCase(ocCircle)) then po := TPlanCircle.Create(Plan)
        else if (AnsiUpperCase(s)=UpperCase(ocText)) then po := TPlanText.Create(Plan)
        else if (AnsiUpperCase(s)=UpperCase(ocPicture)) then po := TPlanPicture.Create(Plan)
        else if (AnsiUpperCase(s)=UpperCase(ocPolygon)) then po := TPlanPolygon.Create(Plan)
        else if (AnsiUpperCase(s)=UpperCase(ocCompositeObject)) then po := TPlanCompositeObject.Create(Plan)
        else if (AnsiUpperCase(s)=UpperCase(ocAniGif)) then po := TPlanAniGif.Create(Plan)
        else if (AnsiUpperCase(s)=UpperCase(ocAniPicture)) then po := TPlanAniPicture.Create(Plan);
        if (po <> nil) then begin
          po.Parent := ao;
          s := Trim(sl[sl.Count - 1]);
          if (Pos(UpperCase(sEndObject),AnsiUpperCase(s)) = 1) then sl.Delete(sl.Count - 1);
          po.Properties.AddStrings(sl);
          po.UpdateObjectProperties;
          po.ID := po.ID + 1;
          if (Plan.ActiveObject <> nil) then Plan.ActiveObject.Unselect;
          po.Select;
          PlanObjectClick(Plan,po,mbLeft,[],0,0);
        end
        else MessageDlg(sUnknownObjectType,mtError,[mbOk],0);
      end;
    end;
  finally
    sl.Free;
  end;
end;

procedure TMainForm.ViewAutoAnimateItemClick(Sender: TObject);
begin
  with ViewAutoAnimateItem do Checked := not Checked;
  if ViewAutoAnimateItem.Checked then Plan.Options := Plan.Options + [poAutoAnimate] else Plan.Options := Plan.Options - [poAutoAnimate];
end;

procedure TMainForm.ViewChildrenClippingItemClick(Sender: TObject);
begin
  with ViewChildrenClippingItem do Checked := not Checked;
  if ViewChildrenClippingItem.Checked then Plan.Options := Plan.Options + [poChildrenClipping] else Plan.Options := Plan.Options - [poChildrenClipping];
end;

procedure TMainForm.SavePicturesItemClick(Sender: TObject);
begin
  with SavePicturesItem do Checked := not Checked;
  if SavePicturesItem.Checked then Plan.Options := Plan.Options + [poSavePictures] else Plan.Options := Plan.Options - [poSavePictures];
end;

procedure TMainForm.SaveBackgroundPictureItemClick(Sender: TObject);
begin
  with SaveBackgroundPictureItem do Checked := not Checked;
  if SaveBackgroundPictureItem.Checked then Plan.Options := Plan.Options + [poSaveBackgroundPicture] else Plan.Options := Plan.Options - [poSaveBackgroundPicture];
end;

procedure TMainForm.SaveStandardPicturesItemClick(Sender: TObject);
begin
  with SaveStandardPicturesItem do Checked := not Checked;
  if SaveStandardPicturesItem.Checked then Plan.Options := Plan.Options + [poSaveStandardPictures] else Plan.Options := Plan.Options - [poSaveStandardPictures];
end;

procedure TMainForm.ExportBitmapItemClick(Sender: TObject);
begin
  with SavePictureDialog do begin
    DefaultExt := 'bmp';
    Filter := 'Bitmaps (*.bmp)|*.bmp';
    if Execute then Plan.ExportToBitmap(FileName);
  end;
end;

procedure TMainForm.ExportMetafileItemClick(Sender: TObject);
begin
  with SavePictureDialog do begin
    DefaultExt := 'wmf';
    Filter := 'Metafiles (*.wmf)|*.wmf';
    if Execute then Plan.ExportToMetafile(FileName);
  end;
end;

procedure TMainForm.ExportJpegItemClick(Sender: TObject);
begin
  with SavePictureDialog do begin
    DefaultExt := 'jpg';
    Filter := 'JPEG Images (*.jpg)|*.jpg';
    if Execute then Plan.ExportToJpeg(FileName);
  end;
end;

procedure TMainForm.ExportGIFItemClick(Sender: TObject);
begin
  with SavePictureDialog do begin
    DefaultExt := 'gif';
    Filter := 'GIF Images (*.gif)|*.gif';
    if Execute then Plan.ExportToGif(FileName);
  end;
end;

procedure TMainForm.PlanCopyToClipboardItemClick(Sender: TObject);
  var b : TBitmap;
begin
  b := Plan.GetBitmap;
  try
    Clipboard.Assign(b);
  finally
    b.Free;
  end;
end;

procedure TMainForm.TransparentCheckClick(Sender: TObject);
begin
  Plan.Transparent := TransparentCheck.Checked;
end;

procedure TMainForm.PlanNeedPicture(Plan: TOxygenPlan; PlanPicture: TPlanPicture);
begin
  if (PlanPicture.Name <> '') then SelectPictureDialog.Title := 'Select the picture for "' + PlanPicture.Name + '"';
  if SelectPictureDialog.Execute then try PlanPicture.Picture.LoadFromFile(SelectPictureDialog.FileName) except end;
  SelectPictureDialog.Title := 'Select picture';
end;

procedure TMainForm.PlanNeedAniGif(Plan: TOxygenPlan; PlanAniGif: TPlanAniGif);
begin
  if (PlanAniGif.Name <> '') then SelectAniGifDialog.Title := 'Select the animated GIF "' + PlanAniGif.Name + '"';
  if SelectAniGifDialog.Execute then try PlanAniGif.GIFImage.LoadFromFile(SelectAniGifDialog.FileName) except end;
  SelectAniGifDialog.Title := 'Select animated GIF';
end;

procedure TMainForm.PlanPaintToDesktopItemClick(Sender: TObject);
begin
  Plan.PaintToDesktop;
end;

procedure TMainForm.PrintSetupItemClick(Sender: TObject);
begin
  PrinterSetupDialog1.Execute;
end;

procedure TMainForm.PrintItemClick(Sender: TObject);
begin
  if PrintDialog1.Execute then Plan.Print(Printer);
end;

function TMainForm.PlanNeedStdAniGif(Plan: TOxygenPlan; const AniGifName: String): Boolean;
  var gif : TGIFImage;
begin
  Result := False;
  gif := TGIFImage.Create;
  try
    if (AniGifName <> '') then SelectAniGifDialog.Title := 'Select the standard animated GIF "' + AniGifName + '"';
    if SelectAniGifDialog.Execute then begin
      gif.LoadFromFile(SelectAniGifDialog.FileName);
      Plan.AddAniGif(AniGifName,gif);
      Result := True;
    end;
  finally
    SelectAniGifDialog.Title := 'Select animated GIF';
    gif.Free;
  end;
end;

function TMainForm.PlanNeedStdPicture(Plan: TOxygenPlan; const PictureName: String): Boolean;
  var pic : TPicture;
begin
  Result := False;
  pic := TPicture.Create;
  try
    if (PictureName <> '') then SelectPictureDialog.Title := 'Select the standard picture "' + PictureName + '"';
    if SelectPictureDialog.Execute then begin
      pic.LoadFromFile(SelectPictureDialog.FileName);
      Plan.AddPicture(PictureName,pic);
      Result := True;
    end;
  finally
    SelectPictureDialog.Title := 'Select picture';
    pic.Free;
  end;
end;

procedure TMainForm.PrintWhiteReplacementColorItemClick(Sender: TObject);
begin
  with ColorSelectDialog do begin
    Color := PlanUtils.clReplaceWhite; // replacement color for clWhite when printing
    if Execute then PlanUtils.clReplaceWhite := Color;
  end;
end;

procedure TMainForm.ObjectMoveItemClick(Sender: TObject);
begin
  if (Plan.ActiveObject = nil) then Exit;
  with MoveResizeDialog do begin
    Caption := 'Move';
    FMove := True;
    PlanObject := Plan.ActiveObject;
    ShowModal;
  end;
end;

procedure TMainForm.ObjectResizeItemClick(Sender: TObject);
begin
  if (Plan.ActiveObject = nil) then Exit;
  with MoveResizeDialog do begin
    Caption := 'Resize';
    FMove := False;
    PlanObject := Plan.ActiveObject;
    ShowModal;
  end;
end;

procedure TMainForm.WWWButtonClick(Sender: TObject);
begin
  ShellExecute(0,'open','http://www.oxygensoftware.com/plan',nil,nil,SW_SHOWNORMAL);
end;

procedure TMainForm.ViewDoubleBufferedItemClick(Sender: TObject);
begin
  with ViewDoubleBufferedItem do Checked := not Checked;
  Plan.DoubleBuffered := ViewDoubleBufferedItem.Checked;
end;

procedure TMainForm.GradientActiveCheckClick(Sender: TObject);
begin
  if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
    GradientRecord.Active := GradientActiveCheck.Checked;
    NeedRepaint;
  end;
end;

procedure TMainForm.GradientColorsEditChange(Sender: TObject);
begin
  if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
    GradientRecord.Colors := GradientColorsEdit.AsInteger;
    NeedRepaint;
  end;
end;

procedure TMainForm.GradientStartColorPanelClick(Sender: TObject);
begin
  if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
    ColorSelectDialog.Color := GradientStartColorPanel.Color;
    if ColorSelectDialog.Execute then begin
      GradientStartColorPanel.Color := ColorSelectDialog.Color;
      GradientRecord.StartColor := ColorSelectDialog.Color;
      NeedRepaint;
    end;
  end;
end;

procedure TMainForm.GradientEndColorPanelClick(Sender: TObject);
begin
  if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
    ColorSelectDialog.Color := GradientEndColorPanel.Color;
    if ColorSelectDialog.Execute then begin
      GradientEndColorPanel.Color := ColorSelectDialog.Color;
      GradientRecord.EndColor := ColorSelectDialog.Color;
      NeedRepaint;
    end;
  end;
end;

procedure TMainForm.GradientDirectionComboChange(Sender: TObject);
begin
  if (Plan.ActiveObject <> nil) then with Plan.ActiveObject do begin
    GradientRecord.Direction := TGradientFillDirection(GradientDirectionCombo.ItemIndex);
    NeedRepaint;
  end;
end;

procedure TMainForm.PlanObjectBlink(Plan: TOxygenPlan; PlanObject: TPlanObject);
begin
  if (PlanObject is TPlanAniGif) and (PlanObject.Name = 'Running cat') then with (PlanObject as TPlanAniGif) do begin
    Move(+5,0);
    if (X1 >= 465) then Move(-X1 + 47,0);
  end;
end;

end.
