home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 October
/
Chip_2001-10_cd1.bin
/
zkuste
/
delphi
/
kompon
/
d123456
/
CHEMPLOT.ZIP
/
TPlot
/
Plotmenu.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2001-07-05
|
22KB
|
648 lines
unit Plotmenu;
{$I Plot.inc}
{-----------------------------------------------------------------------------
The contents of this file are subject to the Q Public License
("QPL"); you may not use this file except in compliance
with the QPL. You may obtain a copy of the QPL from
the file QPL.html in this distribution, derived from:
http://www.trolltech.com/products/download/freelicense/license.html
The QPL prohibits development of proprietary software.
There is a Professional Version of this software available for this.
Contact sales@chemware.hypermart.net for more information.
Software distributed under the QPL is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the QPL for
the specific language governing rights and limitations under the QPL.
The Original Code is: Axis.pas, released 12 September 2000.
The Initial Developer of the Original Code is Mat Ballard.
Portions created by Mat Ballard are Copyright (C) 1999 Mat Ballard.
Portions created by Microsoft are Copyright (C) 1998, 1999 Microsoft Corp.
All Rights Reserved.
Contributor(s): Mat Ballard e-mail: mat.ballard@chemware.hypermart.net.
Last Modified: 02/25/2000
Current Version: 2.00
You may retrieve the latest version of this file from:
http://Chemware.hypermart.net/
This work was created with the Project JEDI VCL guidelines:
http://www.delphi-jedi.org/Jedi:VCLVCL
in mind.
Purpose:
The purpose of this module is to provide the developer using TPlot a quick
method of rapidly implementing menu access to the TPlot functions.
It will be augmented by a TPlotAction module at a later stage.
Known Issues:
- Since TPlotMenu is useless without TPlot, there is only the one
registration unit: TPlot_Reg.pas.
- Is INVISIBLE in D1 Runtime - works perfectly in the designer, but
no menu is present in running applications. If anyone wants to help fix
this, please do so and let me know the answer.
-----------------------------------------------------------------------------}
interface
uses
Classes, SysUtils,
{$IFDEF WINDOWS}
Menus,
{$ENDIF}
{$IFDEF WIN32}
Menus,
{$ENDIF}
{$IFDEF LINUX}
QMenus,
{$ENDIF}
Misc, Plot, Plotdefs;
const
TPLOTMENU_VERSION = 200;
FILE_TAG = 1000;
HELP_TAG = 1095;
ABOUT_TAG = 1096;
REOPEN_TAG = 1097;
EXIT_DIV_TAG = 1098;
EXIT_TAG = 1099;
mnuReopen = 2;
type
TPlotMenu = class(TMainMenu)
private
{The plot to which this menu is linked:}
FPlot: TPlot;
{and the limit of the number of those files:}
FHistoryLimit: Byte;
{Creates the menus after the Plot property is set:}
procedure CreateMenus;
{Creates the Reopen menu item and Submenu and adds it to the File menu:}
procedure CreateReopenSubMenu;
{Gets the History List as a string:}
function GetHistory: String;
protected
{function GetPlot(Target: TObject): TPlot; virtual;}
procedure HandleClick(Sender: TObject);
{The default event handler for all menu items. It forwards the event to TPlot
by calling the latter's HandleClick method, which then passes it onto the
appropriate handler method.}
{$IFNDEF DELPHI1}
procedure HandleClunk(Sender: TObject);
{Called when the menu is clicked on, it sets the Enabled property of all menuitems.}
{$ENDIF}
procedure HandleFileClick(Sender: TObject);
{Called when the a Reopen File menuitem is clicked on.}
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
{Implementation of the standard Notification method for linked components.}
procedure SetPlot(Value: TPlot);
{Sets the pointer to the parental TPlot, creates the menus and their OnClicks}
public
property History: String read GetHistory stored FALSE;
{A History List, CRLF delimited, of previously closed files.
Just use it as:
MyStringList.Create;
MyStringList.Text := PlotMenu1.History;}
constructor Create(AOwner: TComponent); override;
{The standard constructor.}
destructor Destroy; override;
{The standard destructor.}
procedure ApplyOptions(Value: TPopupOptions);
procedure AddHistory(Value: String);
{Adds one more file to the History List.}
function MenuExists(ATag: Integer; ACaption: String): Boolean;
{Does AMenu already exist in Self ?}
{}
{The basis for comparison is both the Tag and Caption}
procedure SetUpOnClicks;
{This assigns the HandleClick and HandleClunk methods to all menu items with
relevant Tags and that are already unassigned.}
published
property HistoryLimit: Byte read FHistoryLimit write FHistoryLimit;
{The limit of the number of files in the History List.}
property Plot: TPlot read FPlot write SetPlot;
{The plot to which TPlotMenu is linked.}
end;
implementation
{Constructor and Destructor ---------------------------------------------------}
{------------------------------------------------------------------------------
Constructor: TPlotMenu.Create
Description: standard Constructor
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: sets the Plot Property
Known Issues:
------------------------------------------------------------------------------}
constructor TPlotMenu.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FPlot := nil;
FHistoryLimit := 10;
end;
{------------------------------------------------------------------------------
Destructor: TPlotMenu.Destroy
Description: standard Destructor
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: frees the Plot Property
Known Issues:
------------------------------------------------------------------------------}
destructor TPlotMenu.Destroy;
begin
if FPlot <> nil then
{$IFDEF DELPHI1}
FPlot.Notification(Self, opRemove);
{$ELSE}
FPlot.FreeNotification(Self);
{$ENDIF}
FPlot := nil;
inherited Destroy;
end;
{Get functions and Set procedures ---------------------------------------------}
{------------------------------------------------------------------------------
Procedure: TPlotMenu.AddHistory
Description: Adds one more file to the History List
Author: Mat Ballard
Date created: 09/01/2000
Date modified: 09/01/2000 by Mat Ballard
Purpose: History List management
Known Issues:
------------------------------------------------------------------------------}
procedure TPlotMenu.AddHistory(Value: String);
var
i: Integer;
pReopen: TMenuItem;
TempMenuItem: TMenuItem;
begin
if (csDestroying in ComponentState) then exit;
if (Length(Value) = 0) then exit;
pReopen := Self.Items[0].Items[mnuReopen];
if (pReopen = nil) then
exit;
{$IFNDEF DELPHI1}
for i := 0 to pReopen.Count-1 do
begin
if (pReopen.Items[i].Hint = Value) then
begin
{Change the order of existing entries:}
pReopen.Items[i].MenuIndex := 0;
exit;
end;
end;
{$ENDIF}
TempMenuItem := TMenuItem.Create(Self);
{Note: we store the full pathname in the Hint because D5 mangles the Caption:
the AutoHotKeys property does not work ! Also looks neater !}
TempMenuItem.Caption := ExtractFileName(Value);
TempMenuItem.Hint := Value;
TempMenuItem.OnClick := HandleFileClick;
pReopen.Insert(0, TempMenuItem);
while (pReopen.Count > FHistoryLimit) do
pReopen.Delete(pReopen.Count-1);
pReopen.Enabled := TRUE;
end;
{------------------------------------------------------------------------------
Procedure: TPlotMenu.GetHistory
Description: Gets the History List as a string.
Author: Mat Ballard
Date created: 08/13/2000
Date modified: 08/13/2000 by Mat Ballard
Purpose: History List management
Known Issues:
------------------------------------------------------------------------------}
function TPlotMenu.GetHistory: String;
var
i: Integer;
TheString: String;
pReopen: TMenuItem;
begin
TheString := '';
pReopen := Self.Items[0].Items[mnuReopen];
for i := 0 to pReopen.Count-1 do
TheString := TheString + pReopen.Items[i].Caption;
GetHistory := TheString;
end;
{------------------------------------------------------------------------------
Procedure: TPlotMenu.SetPlot
Description: standard property Set procedure
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: sets the Plot Property
Known Issues:
------------------------------------------------------------------------------}
procedure TPlotMenu.SetPlot(Value: TPlot);
begin
if Value <> FPlot then
begin
if (Value = nil) then
begin
FPlot := Value;
FPlot.SetPlotMenu(TMainMenu(nil));
end
else
begin
FPlot := Value;
{$IFDEF DELPHI1}
Value.Notification(Self, opInsert); {???}
{$ELSE}
Value.FreeNotification(Self);
{$ENDIF}
CreateMenus;
SetUpOnClicks;
CreateReopenSubMenu;
FPlot.SetPlotMenu(TMainMenu(Self));
end;
end;
end;
{General methods --------------------------------------------------------------}
{------------------------------------------------------------------------------
Procedure: TCustomPlot.CreateMenus
Description: creates popup menus that are accessible by right-click
Author: Mat Ballard
Date created: 12/1/1999
Date modified: 04/20/2000 by Mat Ballard
Purpose: modularize user-interface code
Known Issues: this was a bitch to get right !
------------------------------------------------------------------------------}
procedure TPlotMenu.CreateMenus;
var
i,
j,
HelpMenuIndex: Word;
{This following is just a dummy matrix of menu items used to create sub-menus,
then removed and the menuitems freed.}
TempMenu: array [0..31] of array [0..0] of TMenuItem;
TempMenuItem: TMenuItem;
begin
{don't create menus when the Plot property is streamed in:}
if (csLoading in ComponentState) then exit;
{who needs more than 32 menus ?!}
if (FPlot.PlotPopupMenu.Items.Count > 32) then raise
EComponentError.CreateFmt(sCreateMenus1, [FPlot.PlotPopupMenu.Items.Count]);
{create the sub-menus:}
for i := 0 to FPlot.PlotPopupMenu.Items.Count-1 do
begin
{we create a temporary menu array to add the submenu, and then later remove it:}
TempMenu[i][0] := TMenuItem.Create(Self);
{don't re-create a menu if it already exists:}
if (not MenuExists(
FPlot.PlotPopupMenu.Items[i].Tag,
FPlot.PlotPopupMenu.Items[i].Caption)) then
begin
TempMenuItem := NewSubMenu(
FPlot.PlotPopupMenu.Items[i].Caption,
0,
FPlot.PlotPopupMenu.Items[i].Name,
TempMenu[i]);
TempMenuItem.Tag := FPlot.PlotPopupMenu.Items[i].Tag;
Self.Items.Add(TempMenuItem);
end;
{create the menus in each sub-menu:}
for j := 0 to FPlot.PlotPopupMenu.Items[i].Count-1 do
begin
if (not MenuExists(
FPlot.PlotPopupMenu.Items[i].Items[j].Tag,
FPlot.PlotPopupMenu.Items[i].Items[j].Caption)) then
begin
TempMenuItem := TMenuItem.Create(Self);
TempMenuItem.Caption := FPlot.PlotPopupMenu.Items[i].Items[j].Caption;
TempMenuItem.Name := FPlot.PlotPopupMenu.Items[i].Items[j].Name;
TempMenuItem.Tag := FPlot.PlotPopupMenu.Items[i].Items[j].Tag;
TempMenuItem.Hint := FPlot.PlotPopupMenu.Items[i].Items[j].Hint;
{$IFDEF COMPILER4_UP}
TempMenuItem.ImageIndex := FPlot.PlotPopupMenu.Items[i].Items[j].ImageIndex;
{$ENDIF}
{add the TempMenuItem to the popup:}
Self.Items[i].Add(TempMenuItem);
end;
end; {j over menu items}
{remove the temporary menu array used to create the submenu:}
if (Self.Items[i].Items[0].Caption = '') then
begin
Self.Items[i].Remove(TempMenu[i][0]);
{then free it:}
TempMenu[i][0].Free;
end;
end; {i over submenus}
{don't re-create a menu if it already exists:}
if (Self.Items.Count = FPlot.PlotPopupMenu.Items.Count) then
begin
HelpMenuIndex := FPlot.PlotPopupMenu.Items.Count;
{we now add a "Help" menu:}
{first, we create a temporary menu array to add the submenu, and then later remove it:}
TempMenu[HelpMenuIndex][0] := TMenuItem.Create(Self);
TempMenuItem := NewSubMenu(
sHelp,
0,
'HelpMenu',
TempMenu[HelpMenuIndex]);
TempMenuItem.Tag := HELP_TAG;
Self.Items.Add(TempMenuItem);
{create the "About" menu item:}
TempMenuItem := TMenuItem.Create(Self);
TempMenuItem.Caption := '&' + sAbout + '...';
TempMenuItem.Name := 'AboutMenu';
TempMenuItem.Tag := ABOUT_TAG;
TempMenuItem.Hint := sAuthor;
{add the TempMenuItem to the popup:}
Self.Items[HelpMenuIndex].Add(TempMenuItem);
{remove the temporary menu array used to create the submenu:}
if (Self.Items[HelpMenuIndex].Items[0].Caption = '') then
begin
Self.Items[HelpMenuIndex].Remove(TempMenu[HelpMenuIndex][0]);
{then free it:}
TempMenu[HelpMenuIndex][0].Free;
end;
end;
{Add a divider to the File menu:}
if (not MenuExists(EXIT_DIV_TAG, '-')) then
begin
TempMenuItem := TMenuItem.Create(Self);
TempMenuItem.Caption := '-';
TempMenuItem.Tag := EXIT_DIV_TAG;
Self.Items[0].Add(TempMenuItem);
end;
{Add an "Exit" to the File menu:}
if (not MenuExists(EXIT_TAG, 'E&xit')) then
begin
TempMenuItem := TMenuItem.Create(Self);
TempMenuItem.Caption := sExit;
TempMenuItem.Tag := EXIT_TAG;
TempMenuItem.Name := 'ExitMenuItem';
Self.Items[0].Add(TempMenuItem);
end;
end;
{------------------------------------------------------------------------------
Procedure: TCustomPlot.CreateReopenSubMenu
Description: creates popup menus that are accessible by right-click
Author: Mat Ballard
Date created: 12/1/1999
Date modified: 04/20/2000 by Mat Ballard
Purpose: modularize user-interface code
Known Issues: this was a bitch to get right !
------------------------------------------------------------------------------}
procedure TPlotMenu.CreateReopenSubMenu;
var
{This following is just a dummy matrix of menu items used to create sub-menus,
then removed and the menuitems freed.}
TempMenu: array [0..0] of TMenuItem;
TempMenuItem: TMenuItem;
begin
{don't create menus when the Plot property is streamed in:}
if (csLoading in ComponentState) then exit;
{don't re-create a menu if it already exists:}
if ((Self.Items[0].Items[mnuReopen].Tag = REOPEN_TAG) and
(Self.Items[0].Items[mnuReopen].Caption = sReopen)) then
exit;
{we create a temporary menu array to add the submenu, and then later remove it:}
TempMenu[0] := TMenuItem.Create(Self);
TempMenu[0].Visible := FALSE;
TempMenuItem := NewSubMenu(
sReopen,
0,
'ReopenSubMenu',
TempMenu);
TempMenuItem.Tag := REOPEN_TAG;
{disable the "Reopen" menu because it has no entries:}
{$IFNDEF SHOWALLMENUS}
TempMenuItem.Enabled := FALSE;
{$ENDIF}
Self.Items[0].Insert(mnuReopen, TempMenuItem);
{remove the temporary menu array used to create the submenu:}
Self.Items[0].Items[mnuReopen].Remove(TempMenu[0]);
{then free it:}
TempMenu[0].Free;
end;
{------------------------------------------------------------------------------
Procedure: TPlotMenu.SetUpOnClicks
Description: points all appropriate OnClick event handlers at the TPlot.HandleClick method
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: responding to user menu clicks
Known Issues: have to call this manually (after setting Plot property)
------------------------------------------------------------------------------}
procedure TPlotMenu.SetUpOnClicks;
var
i,
j: Integer;
begin
for i := 0 to Self.Items.Count-1 do
begin
{don't change any existing assignments:}
{$IFNDEF DELPHI1}
if ((Self.Items[i].Tag >= FILE_TAG) and
(Self.Items[i].Tag < EXIT_TAG)) then
if (not Assigned(Self.Items[i].OnClick)) then
Self.Items[i].OnClick := HandleClunk;
{$ENDIF}
for j := 0 to Self.Items[i].Count-1 do
begin
{gotta have a valid tag:}
if ((Self.Items[i].Items[j].Tag >= FILE_TAG) and
(Self.Items[i].Items[j].Tag < EXIT_TAG)) then
begin
{separators don't have OnClicks}
if (Self.Items[i].Items[j].Caption <> '-') then
{don't change any existing assignments:}
{$IFDEF COMPILER2_UP}
if (not Assigned(Self.Items[i].Items[j].OnClick)) then
{$ENDIF}
Self.Items[i].Items[j].OnClick := HandleClick;
end;
end;
end;
end;
{------------------------------------------------------------------------------
Procedure: TPlotMenu.HandleClick
Description: Click Event handler for all menus
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: responds to user clicks of the menus by firing the TPlot method
Known Issues:
------------------------------------------------------------------------------}
procedure TPlotMenu.HandleClick(Sender: TObject);
begin
if (FPlot = nil) then exit;
if (TMenuItem(Sender).Tag < HELP_TAG) then
FPlot.HandleClick(Self, TMenuItem(Sender).Tag)
else if (TMenuItem(Sender).Tag = ABOUT_TAG) then
FPlot.ShowAbout;
end;
{$IFNDEF DELPHI1}
{------------------------------------------------------------------------------
Procedure: TPlotMenu.HandleClunk
Description: Click Event handler for all menus
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: responds to user clicks of the menus by setting the menuitem state (Enabled property)
Known Issues:
------------------------------------------------------------------------------}
procedure TPlotMenu.HandleClunk(Sender: TObject);
begin
if (FPlot = nil) then exit;
FPlot.DetermineMenuEnabledness(Self);
end;
{$ENDIF}
{------------------------------------------------------------------------------
Procedure: TPlotMenu.HandleFileClick
Description: Click Event handler for all Reopen file menus
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: responds to user clicks of the FilaName menus by firing the
TPlot.Open method
Known Issues:
------------------------------------------------------------------------------}
procedure TPlotMenu.HandleFileClick(Sender: TObject);
begin
if (FPlot = nil) then exit;
FPlot.OpenFile(TMenuItem(Sender).Hint);
end;
{------------------------------------------------------------------------------
Procedure: TPlotMenu.Notification
Description: handles changes in Plot property
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: Notifies TPlot that it is no longer loved
Known Issues:
------------------------------------------------------------------------------}
procedure TPlotMenu.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = Plot) then
begin
FPlot := nil;
end;
end;
{------------------------------------------------------------------------------
Function: TPlotMenu.MenuExists
Description: Does this menu exist ? Based on Tag and Caption
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: do we need to add a menu item ?
Return Value: Boolean;
Known Issues:
------------------------------------------------------------------------------}
function TPlotMenu.MenuExists(ATag: Integer; ACaption: String): Boolean;
var
i,
j: Integer;
begin
for i := 0 to Self.Items.Count-1 do
begin
{the menus:}
if ((Self.Items[i].Tag = ATag) and
(Self.Items[i].Caption = ACaption)) then
begin
MenuExists := TRUE;
exit;
end;
for j := 0 to Self.Items[i].Count-1 do
begin
{the submenus:}
if ((Self.Items[i].Items[j].Tag = ATag) and
(Self.Items[i].Items[j].Caption = ACaption)) then
begin
MenuExists := TRUE;
exit;
end;
end;
end;
MenuExists := FALSE;
end;
{------------------------------------------------------------------------------
Procedure: TPlotMenu.ApplyOptions
Description: handles changes Plot.Options property that control menu visibility
Author: Mat Ballard
Date created: 04/25/2000
Date modified: 04/25/2000 by Mat Ballard
Purpose: UI management
Known Issues:
------------------------------------------------------------------------------}
procedure TPlotMenu.ApplyOptions(Value: TPopupOptions);
var
i: Integer;
begin
for i := 0 to Ord(High(TMainMenus)) do
Self.Items[i].Visible :=
(TMainMenus(i) in Value.Menu);
for i := 0 to Ord(High(TFileMenus)) do
Self.Items[Ord(mnuFile)].Items[i].Visible :=
(TFileMenus(i) in Value.File_);
for i := 0 to Ord(High(TEditMenus)) do
Self.Items[Ord(mnuEdit)].Items[i].Visible :=
(TEditMenus(i) in Value.Edit);
for i := 0 to Ord(High(TViewMenus)) do
Self.Items[Ord(mnuView)].Items[i].Visible :=
(TViewMenus(i) in Value.View);
for i := 0 to Ord(High(TCalcMenus)) do
Self.Items[Ord(mnuCalc)].Items[i].Visible :=
(TCalcMenus(i) in Value.Calc);
end;
end.