mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-09 16:52:36 +02:00

sparta: initial commit of "compilable" new sparta package - smart form editor. !NOTE: not for daily usage. ........ sparta: Initial conception for package for MDI: sparta_MDI. Base for sparta_DockedFormEditor package. ........ sparta: Generics.Collections library ( sync with https://github.com/dathox/generics.collections SHA fda586932bd80ef58c08f8ebf5a24316ca4ccca5) ........ sparta: smart form editor adjustment for new sparta_MDI ........ sparta: new class "TFormImpl" for MDI solution (created from TDesignedFormImpl). ........ sparta: -MDI form container "TFormContainer" -New IResizeFrame interface to handle MDI form moving -New frame TfrFormBackgroundForMDI ........ sparta: sparta_MDI package modifications: -new class TMultiplyResizer to menage MDI desktop -more generic resizer: TAbstractResizer. Base for IDE resizer and TMultiplyResizer -more advanced IResizeFrame interface ........ sparta: -DockedFormEditor adjustment for latest changes in mdi package -small changes in mdi (visibility of methods). -OnModified method for IResizeFrame ........ sparta: MDI -simulate MDI forms order for TMultiplyResizer -property DesignedForm: IDesignedForm for IResizeFrame ........ sparta: -IMPORTANT! pixel perfect form resizing (fix for problems for controls with align alLeft, alRight etc on design form). -Fix problem for windows: wrong design design window width (a little bigger than designed size) TFormImpl.SetRealBounds -> AdjustSize ........ sparta: mdi bug fix for AV in TMultiplyResizer ........ Fix compilation for FPC 3.0 (TRect changes in FPC 3.1 trunk) ........ sparta: Cannot resize the docked form designer, issue #29380 patch from Anthony Walter. Thanks! ........ sparta ToolsAPI: Delphi compatible ToolsAPI/DesignIDE interface at XE2 level (proxy for IDEIntf). Initial commit (no functionality yet), just interfaces and classes without implementation: designeditors.pas: -TComponentEditor designintf.pas: -Interfaces: IEventInfo, IClass, IActivatable, IDesignObject, IDesignPersistent, IDesignerSelections, IDesigner60, IDesigner70, IDesigner80, IDesigner100, IDesigner, IComponentEditor -TBaseComponentEditor -RegisterComponentEditor designmenus.pas: -Interfaces: IMenuItems, IMenu, IMainMenu, IPopupMenu, IMenuItem ........ when form is removed we need to remove all handlers located in collections FFormsStack and FForms. Necessary to avoid AV. ........ sparta: more correct and simpler calculation of form border for Windows ........ sparta: * Fix for loop error for resize. Highly visible problem for docked forms/frames with Align=alClient. * New THookFrame class as new meta class for Frames. ........ updated lpl ........ git-svn-id: trunk@52728 -
219 lines
7.8 KiB
ObjectPascal
219 lines
7.8 KiB
ObjectPascal
// Generic types for FreeSparta.com and FreePascal!
|
||
// Original version by keeper89.blogspot.com, 2011
|
||
// FPC version by Maciej Izak (hnb), 2014
|
||
|
||
program THashMapProject;
|
||
|
||
{$MODE DELPHI}
|
||
{$APPTYPE CONSOLE}
|
||
|
||
uses
|
||
SysUtils, Generics.Collections, Generics.Defaults;
|
||
|
||
type
|
||
TSubscriberInfo = record
|
||
Name, SName: string;
|
||
class function Create(const Name, SName: string): TSubscriberInfo; static;
|
||
function ToString: string;
|
||
end;
|
||
|
||
// Class containing handlers add / remove items in the dictionary
|
||
THashMapEventsHandler = class
|
||
public
|
||
class procedure OnKeyNotify(Sender: TObject; constref Item: string;
|
||
Action: TCollectionNotification);
|
||
class procedure OnValueNotify(Sender: TObject; constref Item: TSubscriberInfo;
|
||
Action: TCollectionNotification);
|
||
end;
|
||
|
||
class function TSubscriberInfo.Create(const Name,
|
||
SName: string): TSubscriberInfo;
|
||
begin
|
||
Result.Name := Name;
|
||
Result.SName := SName;
|
||
end;
|
||
|
||
function TSubscriberInfo.ToString: string;
|
||
begin
|
||
Result := Format('%s %s', [Name, SName]);
|
||
end;
|
||
|
||
// Function to generate the dictionary contents into a string
|
||
function PrintTelephoneDirectory(
|
||
TelephoneDirectory: THashMap<string, TSubscriberInfo>): string;
|
||
var
|
||
PhoneNumber: string;
|
||
begin
|
||
Result := Format('Content directory (%d):', [TelephoneDirectory.Count]);
|
||
|
||
for PhoneNumber in TelephoneDirectory.Keys do
|
||
Result := Result + Format(LineEnding + '%s: %s',
|
||
[PhoneNumber, TelephoneDirectory[PhoneNumber].ToString]);
|
||
end;
|
||
|
||
// Handlers add / remove items dictionary
|
||
class procedure THashMapEventsHandler.OnKeyNotify(Sender: TObject;
|
||
constref Item: string; Action: TCollectionNotification);
|
||
begin
|
||
case Action of
|
||
cnAdded:
|
||
Writeln(Format('OnKeyNotify! Phone %s added!', [Item]));
|
||
cnRemoved:
|
||
Writeln(Format('OnKeyNotify! Number %s deleted!', [Item]));
|
||
end;
|
||
end;
|
||
|
||
class procedure THashMapEventsHandler.OnValueNotify(Sender: TObject;
|
||
constref Item: TSubscriberInfo; Action: TCollectionNotification);
|
||
begin
|
||
case Action of
|
||
cnAdded:
|
||
Writeln(Format('OnValueNotify! Subscriber %s added!', [Item.ToString]));
|
||
cnRemoved:
|
||
Writeln(Format('OnValueNotify! Subscriber %s deleted!', [Item.ToString]));
|
||
end;
|
||
end;
|
||
|
||
function CustomCompare(constref Left, Right: TPair<string, TSubscriberInfo>): Integer;
|
||
begin
|
||
// Comparable full first names, and then phones if necessary
|
||
Result := TCompare.&String(Left.Value.ToString, Right.Value.ToString);
|
||
if Result = 0 then
|
||
Result := TCompare.&String(Left.Key, Right.Key);
|
||
end;
|
||
|
||
var
|
||
// Declare the "dictionary"
|
||
// key is the telephone number which will be possible
|
||
// to determine information about the owner
|
||
TelephoneDirectory: THashMap<string, TSubscriberInfo>;
|
||
TTelephoneArray: array of TPair<string, TSubscriberInfo>;
|
||
TTelephoneArrayItem: TPair<string, TSubscriberInfo>;
|
||
PhoneNumber: string;
|
||
Subscriber: TSubscriberInfo;
|
||
begin
|
||
WriteLn('Working with THashMap - phonebook');
|
||
WriteLn;
|
||
|
||
// create a directory
|
||
// Constructor has several overloaded options which will
|
||
// enable the capacity of the container, a comparator for values
|
||
// or the initial data - we use the easiest option
|
||
TelephoneDirectory := THashMap<string, TSubscriberInfo>.Create;
|
||
|
||
// ---------------------------------------------------
|
||
// 1) Adding items to dictionary
|
||
|
||
// Add new users to the phonebook
|
||
TelephoneDirectory.Add('9201111111', TSubscriberInfo.Create('Arnold', 'Schwarzenegger'));
|
||
TelephoneDirectory.Add('9202222222', TSubscriberInfo.Create('Jessica', 'Alba'));
|
||
TelephoneDirectory.Add('9203333333', TSubscriberInfo.Create('Brad', 'Pitt'));
|
||
TelephoneDirectory.Add('9204444444', TSubscriberInfo.Create('Brad', 'Pitt'));
|
||
TelephoneDirectory.Add('9205555555', TSubscriberInfo.Create('Sandra', 'Bullock'));
|
||
// Adding a new subscriber if number already exist
|
||
TelephoneDirectory.AddOrSetValue('9204444444',
|
||
TSubscriberInfo.Create('Angelina', 'Jolie'));
|
||
// Print list
|
||
Writeln(PrintTelephoneDirectory(TelephoneDirectory));
|
||
|
||
// ---------------------------------------------------
|
||
// 2) Working with the elements
|
||
|
||
// Set the "capacity" of the dictionary according to the current number of elements
|
||
TelephoneDirectory.TrimExcess;
|
||
// Is there a key? - ContainsKey
|
||
if TelephoneDirectory.ContainsKey('9205555555') then
|
||
Writeln('Phone 9205555555 registered!');
|
||
// Is there a subscriber? - ContainsValue
|
||
Subscriber := TSubscriberInfo.Create('Sandra', 'Bullock');
|
||
if TelephoneDirectory.ContainsValue(Subscriber) then
|
||
Writeln(Format('%s is in the directory!', [Subscriber.ToString]));
|
||
// Try to get information via telephone. TryGetValue
|
||
if TelephoneDirectory.TryGetValue('9204444444', Subscriber) then
|
||
Writeln(Format('Number 9204444444 belongs to %s', [Subscriber.ToString]));
|
||
// Directly access by phone number
|
||
Writeln(Format('Phone 9201111111 subscribers: %s', [TelephoneDirectory['9201111111'].ToString]));
|
||
// Number of people in the directory
|
||
Writeln(Format('Total subscribers in the directory: %d', [TelephoneDirectory.Count]));
|
||
|
||
// ---------------------------------------------------
|
||
// 3) Delete items
|
||
|
||
// Schwarzenegger now will not be listed
|
||
TelephoneDirectory.Remove('9201111111');
|
||
// Completely clear the list
|
||
TelephoneDirectory.Clear;
|
||
|
||
// ---------------------------------------------------
|
||
// 4) Events add / remove values
|
||
//
|
||
// Events OnKeyNotify OnValueNotify are designed for "tracking"
|
||
// for adding / removing keys and values respectively
|
||
TelephoneDirectory.OnKeyNotify := THashMapEventsHandler.OnKeyNotify;
|
||
TelephoneDirectory.OnValueNotify := THashMapEventsHandler.OnValueNotify;
|
||
|
||
Writeln;
|
||
// Try events
|
||
TelephoneDirectory.Add('9201111111', TSubscriberInfo.Create('Arnold', 'Schwarzenegger'));
|
||
TelephoneDirectory.Add('9202222222', TSubscriberInfo.Create('Jessica', 'Alba'));
|
||
TelephoneDirectory['9202222222'] := TSubscriberInfo.Create('Monica', 'Bellucci');
|
||
TelephoneDirectory.Clear;
|
||
WriteLn;
|
||
|
||
TelephoneDirectory.Add('9201111111', TSubscriberInfo.Create('Monica', 'Bellucci'));
|
||
TelephoneDirectory.Add('9202222222', TSubscriberInfo.Create('Sylvester', 'Stallone'));
|
||
TelephoneDirectory.Add('9203333333', TSubscriberInfo.Create('Bruce', 'Willis'));
|
||
WriteLn;
|
||
|
||
// Show keys (phones)
|
||
Writeln('Keys (phones):');
|
||
for PhoneNumber in TelephoneDirectory.Keys do
|
||
Writeln(PhoneNumber);
|
||
Writeln;
|
||
|
||
// Show values (subscribers)
|
||
Writeln('Values (subscribers):');
|
||
for Subscriber in TelephoneDirectory.Values do
|
||
Writeln(Subscriber.ToString);
|
||
Writeln;
|
||
|
||
// All together now
|
||
Writeln('Subscribers list with phones:');
|
||
for PhoneNumber in TelephoneDirectory.Keys do
|
||
Writeln(Format('%s: %s',
|
||
[PhoneNumber, TelephoneDirectory[PhoneNumber].ToString]));
|
||
Writeln;
|
||
|
||
// In addition, we can "export" from the dictionary
|
||
// to TArray
|
||
// Sort the resulting array and display
|
||
TTelephoneArray := TelephoneDirectory.ToArray;
|
||
|
||
// partial specializations not allowed
|
||
// same for anonymous methods
|
||
//TArray.Sort<TPair<string, TSubscriberInfo>>(
|
||
// TTelephoneArray, TComparer<TPair<string, TSubscriberInfo>>.Construct(
|
||
// function (const Left, Right: TPair<string, TSubscriberInfo>): Integer
|
||
// begin
|
||
// // Comparable full first names, and then phones if necessary
|
||
// Result := CompareStr(Left.Value.ToString, Right.Value.ToString);
|
||
// if Result = 0 then
|
||
// Result := CompareStr(Left.Key, Right.Key);
|
||
// end));
|
||
|
||
TArrayHelper<TelephoneDirectory.TDictionaryPair>.Sort(
|
||
TTelephoneArray, TComparer<TelephoneDirectory.TDictionaryPair>.Construct(
|
||
CustomCompare));
|
||
// Print
|
||
Writeln('Sorted list of subscribers into TArray (by name, and eventually by phone):');
|
||
for TTelephoneArrayItem in TTelephoneArray do
|
||
Writeln(Format('%s: %s',
|
||
[TTelephoneArrayItem.Value.ToString, TTelephoneArrayItem.Key]));
|
||
|
||
Writeln;
|
||
FreeAndNil(TelephoneDirectory);
|
||
|
||
Readln;
|
||
end.
|
||
|