From d617abcccad6948456d1091aa2651cafff90c510 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sat, 19 Apr 2014 19:29:13 +0000 Subject: [PATCH] fpspreadsheet: Major re-write of fpspreadsheetgrid: - persistent storage of workbook - inherits from TCustomDrawGrid instead of from TCustomStringGrid - use FixedRow/Col for row/column headers - displays cell borders as read from the file - uses column widths as read from the file (approximate only) - numbers are right-aligned by default. - demo extended to display worksheets in tabs - some visual improvements of demo - saving not yet working in demo More to follow... git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2951 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../examples/fpsgrid/fpsgrid.lpr | 2 +- .../examples/fpsgrid/mainform.lfm | 264 ++++++++++++++-- .../examples/fpsgrid/mainform.lrs | 222 +++++++++++-- .../examples/fpsgrid/mainform.pas | 95 ++++-- components/fpspreadsheet/fpspreadsheet.pas | 2 +- .../fpspreadsheet/fpspreadsheetgrid.pas | 294 +++++++++++++----- components/fpspreadsheet/fpsutils.pas | 23 ++ components/fpspreadsheet/xlsbiff8.pas | 56 +--- 8 files changed, 758 insertions(+), 200 deletions(-) diff --git a/components/fpspreadsheet/examples/fpsgrid/fpsgrid.lpr b/components/fpspreadsheet/examples/fpsgrid/fpsgrid.lpr index 3a92ca33d..85e702ea5 100644 --- a/components/fpspreadsheet/examples/fpsgrid/fpsgrid.lpr +++ b/components/fpspreadsheet/examples/fpsgrid/fpsgrid.lpr @@ -7,7 +7,7 @@ uses Forms, mainform, LResources, laz_fpspreadsheet_visual { you can add units after this }; -//{$IFDEF WINDOWS}{$R fpsvisual.rc}{$ENDIF} +{$R *.res} begin Application.Initialize; diff --git a/components/fpspreadsheet/examples/fpsgrid/mainform.lfm b/components/fpspreadsheet/examples/fpsgrid/mainform.lfm index 201bf4710..ce41b2d06 100644 --- a/components/fpspreadsheet/examples/fpsgrid/mainform.lfm +++ b/components/fpspreadsheet/examples/fpsgrid/mainform.lfm @@ -3,58 +3,270 @@ object Form1: TForm1 Height = 339 Top = 177 Width = 400 - Caption = 'FPSVisual' + Caption = 'fpsGrid' ClientHeight = 319 ClientWidth = 400 Menu = MainMenu1 + ShowHint = True LCLVersion = '1.3' - object sWorksheetGrid1: TsWorksheetGrid - Left = 8 - Height = 192 - Top = 48 - Width = 384 - TabOrder = 0 - end - object buttonPopulateGrid: TButton - Left = 136 - Height = 25 + object Panel1: TPanel + Left = 0 + Height = 55 Top = 264 - Width = 112 - Caption = 'Populate Grid' - OnClick = buttonPopulateGridClick + Width = 400 + Align = alBottom + BevelOuter = bvNone + ClientHeight = 55 + ClientWidth = 400 + TabOrder = 0 + object btnPopulateGrid: TButton + Left = 280 + Height = 25 + Top = 8 + Width = 112 + Caption = 'Populate Grid' + OnClick = btnPopulateGridClick + TabOrder = 0 + Visible = False + end + object CbDisplayFixedColRow: TCheckBox + Left = 8 + Height = 19 + Top = 8 + Width = 130 + Caption = 'Display fixed col/row' + Checked = True + OnClick = CbDisplayFixedColRowClick + State = cbChecked + TabOrder = 1 + end + object CbDisplayGrid: TCheckBox + Left = 8 + Height = 19 + Top = 29 + Width = 82 + Caption = 'Display grid' + Checked = True + OnClick = CbDisplayGridClick + State = cbChecked + TabOrder = 2 + end + end + object PageControl1: TPageControl + Left = 0 + Height = 238 + Top = 26 + Width = 400 + ActivePage = TabSheet1 + Align = alClient + TabIndex = 0 TabOrder = 1 + OnChange = PageControl1Change + object TabSheet1: TTabSheet + Caption = 'Sheet1' + ClientHeight = 210 + ClientWidth = 392 + object sWorksheetGrid1: TsWorksheetGrid + Left = 0 + Height = 210 + Top = 0 + Width = 392 + Align = alClient + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goThumbTracking, goSmoothScroll, goCellEllipsis] + TabOrder = 0 + TitleStyle = tsNative + end + end + end + object ToolBar1: TToolBar + Left = 0 + Height = 26 + Top = 0 + Width = 400 + Caption = 'ToolBar1' + EdgeBorders = [] + Images = ImageList1 + TabOrder = 2 + object ToolButton1: TToolButton + Left = 1 + Top = 0 + Action = AcOpen + end + object ToolButton2: TToolButton + Left = 24 + Top = 0 + Action = AcSaveAs + end + object ToolButton3: TToolButton + Left = 52 + Top = 0 + Action = AcQuit + end + object ToolButton5: TToolButton + Left = 47 + Top = 0 + Width = 5 + Caption = 'ToolButton5' + Style = tbsDivider + end end object OpenDialog1: TOpenDialog DefaultExt = '.xls' Filter = 'Excel spreadsheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlxs|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|Wikitable (pipes) (.wikitable_pipes)|.wikitable_pipes|All files (*.*)|*.*' Options = [ofExtensionDifferent, ofEnableSizing, ofViewDetail] - left = 8 - top = 264 + left = 64 + top = 176 end object SaveDialog1: TSaveDialog DefaultExt = '.xls' Filter = 'Excel spreadsheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlsx|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|Wikitable (wikimedia) (.wikitable_wikimedia)|*.wikitable_wikimedia' Options = [ofExtensionDifferent, ofEnableSizing, ofViewDetail] - left = 72 - top = 264 + left = 176 + top = 176 end object MainMenu1: TMainMenu - left = 296 - top = 264 + Images = ImageList1 + left = 288 + top = 176 object mnuFile: TMenuItem Caption = '&File' object mnuOpen: TMenuItem - Caption = '&Open...' - OnClick = mnuOpenClick + Action = AcOpen + OnClick = acOpenExecute end object mnuSaveAs: TMenuItem - Caption = '&Save as...' - OnClick = mnuSaveAsClick + Action = AcSaveAs + OnClick = acSaveAsExecute + end + object MenuItem1: TMenuItem + Caption = '-' end object mnuQuit: TMenuItem - Caption = '&Quit' - OnClick = mnuQuitClick + Action = AcQuit + OnClick = acQuitExecute end end end + object ImageList1: TImageList + left = 176 + top = 120 + Bitmap = { + 4C69030000001000000010000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00EAC39DFFE6BF96FFE4BB92FFE4BB92FFD1A06CF5D09E6DF6CC96 + 5FDAC479427EB2673C09FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E5BE96FFFFFFFEFFFDF3E9FFFDF3EAFFFCF2E8FFFAEFE3FFFAF2 + E7FFEABB88FFCF8555B3B4693D0CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E4BB93FFFEF5EDFFFCDEC5FFFBE0C7FFF9DCC2FFF5D3B4FFFEF9 + F3FFFAE2C4FFECC193FFC37D4893FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E4BB92FFFEF6F0FFFCE2CDFFFCE3CDFFFADFC8FFF7D9BCFFF5E9 + DDFFFAF3EBFFFBF8F3FFCA8353FEFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E4BB92FFFEF7F1FFFCE5D2FFFCE4D1FFFBE2CCFFF9DDC4FFF6D7 + BBFFF3D1AFFFFAEFE4FFCC8758FE34B4D9D05EC2E1FA60C3E2FA60C3E2FA60C3 + E2FA5FC3E2FAE4BB91FFFFF7F2FFFEE7D5FFFEE7D5FFFDE5D1FFFAE0CAFFF9DE + C4FFF7D9BCFFFDF2E7FFCC8757FE36B3DAF8FDFEFEFFFEFFFFFFFEFEFFFFFDFE + FFFFFEFFFFFFE4BA91FFFFF7F0FFFFE7D5FFFDE7D6FFFDE6D4FFFCE4D0FFFBE3 + CBFFFADCC2FFFEF3E8FFCC8656FE35AFDAF0F7FCFEFF8EE4F8FF91DEF5FF9FE0 + F5FFACE1F6FFCA8452FFFFF7F1FFFFE9D9FFFFEADBFFFFE9D9FFFFE7D7FFFFE5 + D2FFFFE2CBFFFFF7F1FFCB8555FE36AADAF2F1FAFDFF94DEF5FF93DCF4FF64BC + E9FF3594DAFF3594DAFF3594DAFF3594DAFF3594DAFF3594DAFF3594DAFF3594 + DAFF3594DAFFFBF6EFFFCC8355FE35ABDAFAE8F6FBFF70BCE7FF55AAE2FF4DA5 + E0FF91C9EBFFFAF3EFFFFDFEFDFFFFFDFCFFFFFDFCFFFEFDFCFFFEFCFBFFFEFE + FDFF3594DAFFEFF2E8FFCE8156FF37A6DAFAFEFFFFFFF8FDFFFFF6FDFFFFF5FC + FFFFF3FCFEFF9AE4F4FF9AE6F7FF9BE6F6FF9DE5F5FF9EE5F5FF9FE5F4FFDAF3 + F8FF3594DAFFFDF4EEFFCA8054F936A1DAF9F6FCFEFF94E5F8FF93E5F8FF93E5 + F8FF91E5F8FF93DBE9FF93D7E3FF93D2DCFF90CED7FF8CC8CFFF86C1C6FFC9D8 + D6FF3594DAFFC57444E8CA7F53F1369ADAF8F2FAFDFF94E6F8FF92E5F8FF90E5 + F8FF8BE3F8FF86E2F7FF7FE1F7FF77DEF6FF6CDCF6FF5ED9F4FF4FD5F3FFCCF2 + FBFF3594DAFFFFFFFF00FFFFFF003594DAF7EFFAFEFF93E5F8FF8FE4F8FF89E3 + F8FF82E1F7FF7ADFF7FF71DEF6FF67DBF5FF5BD8F4FF4DD4F3FF40D1F2FFCAF2 + FBFF3594DAFFFFFFFF00FFFFFF00338ED9FBDCF0FAFF98E1F6FF95E0F6FF92DF + F6FF8EDEF5FF89DCF5FF85DAF4FF80D9F4FF7AD7F3FF74D5F3FF70D3F2FFC2EA + F8FF3594DAFFFFFFFF00FFFFFF002C86D8002D88D8F72D87D8F72D88D8F72D88 + D8F72D88D8F72D88D8F72D88D8F72D88D8F72D88D8F72D88D8F72D87D8F72D88 + D8F72C86D800FFFFFF00FFFFFF00BC6B3671BC6B3690BC6B36CCBC6B36EEBC6B + 36FABB6B36FEBB6B36FFBB6A36FFBB6A36FFBC6C39FFBD6E3BFFBB6D3AFFBB6B + 38EFBB703ECBB6693554FFFFFF00BC6B369BF6E0D1FFF7E0D1FFFEFBF8FFFEFB + F7FFFDF9F6FFFCF5F0FFFAF0EAFFFBF2EDFFFDF9F6FFFDFAF7FFFBF1EBFFF8E9 + DFFEECD0BDFBC9895EECB5693563BC6B36D8F6DFD1FFE9AA80FFFEFAF6FFFDFA + F6FFC88C64FFFBF3EEFFFBF1EAFFFCF6F2FFFEFBF8FFFCF6F1FFF9ECE2FFF8E7 + DBFFEED0BAFFECD0BDFFBB703EF8BC6B36F0F6DFD0FFE8A87EFFFCF6F1FFFCF6 + F1FFC88C64FFFAF1E9FFFBF4EEFFFDFAF7FFFDF9F6FFFAF0E8FFF8E8DDFFF7E6 + DBFFE1A37AFFEFD5C3FFB76935FEBC6B36FAF5DDCCFFE7A87EFFFAF0E8FFFAF0 + E8FFC98D66FFFAF0E9FFFDF8F3FFFEFAF8FFFCF4EFFFF9E9DFFFF7E7DBFFF7E5 + D9FFE0A278FFE7C2A9FFB66835FFBB6B36FEF4DCC9FFE7A77DFFF9ECE1FFF9EC + E1FFF9EDE3FFFCF4EEFFFDFAF7FFFDF7F3FFFAEDE5FFF7E7DBFFF7E5D9FFF6E5 + D8FFDEA077FFE4BEA4FFB46734FFBB6B36FFF4D9C7FFE6A67DFFC88C64FFC98D + 65FFC98E67FFCB926CFFCB926DFFCA9069FFC88C65FFC88C64FFC88C64FFC88C + 64FFDA9C74FFE1BA9FFFB36634FFBB6A36FFF2D8C5FFE3A47BFFE3A37AFFE3A4 + 7AFFE2A47BFFE2A37BFFE1A37BFFE1A279FFDFA077FFDE9F76FFDD9E74FFDB9C + 72FFDC9D74FFDDB59AFFB16534FFBB6A36FFF2D5C2FFE3A37AFFE3A37AFFE2A3 + 7BFFE2A37BFFE2A47BFFE1A279FFE0A178FFDEA077FFDE9E75FFDC9D74FFDA9B + 73FFD99B73FFDAB095FFAF6433FFBB6A36FFF0D2BEFFE2A37AFFE2A37AFFE1A3 + 7AFFE2A37BFFE1A37BFFE0A178FFDE9F77FFDD9F76FFDC9D74FFD99B72FFD899 + 71FFD69970FFD5AB8EFFAD6333FFBA6A36FFEFD0BBFFE2A27AFFFEFBF8FFFEFB + F8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFB + F8FFD3966DFFD2A78AFFAB6232FFBB6B38FFEFCEB8FFE1A279FFFEFAF7FF62C0 + 88FF62C088FF62C088FF62C088FF62C088FF62C088FF62C088FF62C088FFFDF9 + F6FFCF936AFFCEA384FFAA6132FFBB6C38FFEECCB6FFE1A27AFFFEFAF7FFBFDC + C2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFFDF9 + F6FFCD9068FFCC9E81FFA86132FFBA6B37FEEDCAB3FFE0A27AFFFEFAF7FF62C0 + 88FF62C088FF62C088FF62C088FF62C088FF62C088FF62C088FF62C088FFFDF9 + F6FFCA8D65FFC99B7CFFA76031FEBA6A35DEEBC6ADFFEAC5ADFFFEFBF8FFFEFB + F8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFB + F8FFC89A7CFFC79879FFA76031EDBA6A3600B96935B5B86935EEB76835FFB568 + 35FFB46734FFB26634FFB06533FFAE6433FFAC6332FFAA6232FFA96132FFA860 + 31FFA76031FEA66031F1A86131C4FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF006D9CD4896A9AD2FB6697CFEEFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00709ED6DB6D9C + D4FF85B1DAFF5A91B9FF6093CBEAFFFFFF00FFFFFF00808080FF7E7E7EFF7C7C + 7CFF7A7A7AFF777777FF757575FF727272FF719ED4FF6F9ED6FF87B2DCFFABD3 + E8FFA9D0E6FF5890B8FF598EC6EAFFFFFF00FFFFFF007D7D7DFF999999FF9999 + 99FF9A9A9AFF9A9A9AFF9B9B9BFF9B9B9BFF6F9DD3FFAAD1E7FFABD1E7FF98C7 + E1FF91C2DEFF568FB7FF5289C1EAFFFFFF00FFFFFF007A7A7AFF999999FF5291 + 59FF999A99FF9B9B9BFF9C9C9CFF9C9C9CFF6C9AD0FFA7CEE5FF8FC1DFFF89BD + DCFF8BBDDCFF538DB6FF4B84BCEAFFFFFF00FFFFFF00777777FF9A9A9AFF3D8A + 45FF498A4FFF9C9C9CFF9D9D9DFF9D9D9DFF6696CCFFA2CBE3FF89BDDCFF83B9 + DAFF84B9DAFF518BB5FF437EB6EA44944DFF42914BFF3F8D48FF3D8945FF5DA4 + 65FF5AA061FF45834BFF9E9E9EFF9E9E9EFF6092C9FF9EC7E2FF83B8DAFF7DB4 + D7FF7EB3D7FF4F89B4FF3B79B1EA41904AFF94D29FFF91D09AFF8DCD96FF89CB + 92FF84C88DFF519858FF417C46FF9F9F9FFF5A8EC4FF98C3E0FF7CB3D7FF74AF + D6FF5EC4EDFF4B88B3FF3473ABEA3E8B46FF8FCE99FF7DC687FF78C381FF73C0 + 7CFF74C07CFF79C281FF49904FFF547F57FF5489BFFF94BFDDFF75ADD4FF63B8 + E1FF4BD4FFFF428BB8FF2C6EA6EA3B8742FF89CB92FF84C88DFF80C688FF7BC3 + 83FF77C17FFF478F4DFF3B743FFFA1A1A1FF4C84BAFF8DBBDBFF6EA8D1FF66A6 + D1FF5FB4DFFF4785B1FF2569A1EA37823EFF347E3BFF317937FF2E7534FF4991 + 50FF468F4CFF39733DFFA1A1A1FFA2A2A2FF457EB4FF88B7D9FF67A3CFFF619E + CCFF639FCCFF4583B1FF1F649CEAFFFFFF00FFFFFF00606060FFA0A0A0FF3D76 + 41FF367139FFA2A2A2FFA2A2A2FFA3A3A3FF3D79B0FF82B3D7FF629FCCFF5A9A + C9FF5E9BCAFF4381AFFF196098EAFFFFFF00FFFFFF005C5C5CFFA1A1A1FF3C73 + 40FFA0A1A1FFA3A3A3FFA3A3A3FFA4A4A4FF3674AAFF7DAFD4FF5B9AC9FF5495 + C7FF5896C8FF4180AEFF135C94EAFFFFFF00FFFFFF00585858FFA2A2A2FFA2A2 + A2FFA3A3A3FFA4A4A4FFA4A4A4FFA5A5A5FF2F6FA5FF78ABD2FF78ABD3FF73A7 + D1FF69A0CDFF407FAEFF0F5991EA999999FF717171FF545454FF515151FF4F4F + 4FFF4C4C4CFF4A4A4AFF474747FF454545FF25679DFF3274A8FF3D7CAFFF4784 + B5FF4E8ABAFF3E7EADFF0C578FEAFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF001D639B1619609839145D9562105A + 92880D5890A4135C92FC0C578FED + } + end + object ActionList1: TActionList + left = 176 + top = 64 + object AcOpen: TAction + Caption = 'Open...' + ImageIndex = 0 + OnExecute = acOpenExecute + end + object AcSaveAs: TAction + Caption = 'Save as...' + ImageIndex = 1 + OnExecute = acSaveAsExecute + end + object AcQuit: TAction + Caption = 'Quit' + ImageIndex = 2 + OnExecute = acQuitExecute + end + end end diff --git a/components/fpspreadsheet/examples/fpsgrid/mainform.lrs b/components/fpspreadsheet/examples/fpsgrid/mainform.lrs index ac317fa3e..ca9452d3f 100644 --- a/components/fpspreadsheet/examples/fpsgrid/mainform.lrs +++ b/components/fpspreadsheet/examples/fpsgrid/mainform.lrs @@ -2,25 +2,205 @@ LazarusResources.Add('TForm1','FORMDATA',[ 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3' '#1#6'Height'#3'S'#1#3'Top'#3#177#0#5'Wi' - +'dth'#3#144#1#7'Caption'#6#9'FPSVisual'#12'ClientHeight'#3'?'#1#11'ClientWid' - +'th'#3#144#1#4'Menu'#7#9'MainMenu1'#10'LCLVersion'#6#3'1.3'#0#15'TsWorksheet' - +'Grid'#15'sWorksheetGrid1'#4'Left'#2#8#6'Height'#3#192#0#3'Top'#2'0'#5'Width' - +#3#128#1#8'TabOrder'#2#0#0#0#7'TButton'#18'buttonPopulateGrid'#4'Left'#3#136 - +#0#6'Height'#2#25#3'Top'#3#8#1#5'Width'#2'p'#7'Caption'#6#13'Populate Grid'#7 - +'OnClick'#7#23'buttonPopulateGridClick'#8'TabOrder'#2#1#0#0#11'TOpenDialog' - +#11'OpenDialog1'#10'DefaultExt'#6#4'.xls'#6'Filter'#6#192'Excel spreadsheet ' - +'(*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlxs|LibreOffice/OpenOffice ' - +'spreadsheet (*.ods)|*.ods|Wikitable (pipes) (.wikitable_pipes)|.wikitable_p' - +'ipes|All files (*.*)|*.*'#7'Options'#11#20'ofExtensionDifferent'#14'ofEnabl' - +'eSizing'#12'ofViewDetail'#0#4'left'#2#8#3'top'#3#8#1#0#0#11'TSaveDialog'#11 - +'SaveDialog1'#10'DefaultExt'#6#4'.xls'#6'Filter'#6#185'Excel spreadsheet (*.' - +'xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlsx|LibreOffice/OpenOffice spr' - +'eadsheet (*.ods)|*.ods|Wikitable (wikimedia) (.wikitable_wikimedia)|*.wikit' - +'able_wikimedia'#7'Options'#11#20'ofExtensionDifferent'#14'ofEnableSizing'#12 - +'ofViewDetail'#0#4'left'#2'H'#3'top'#3#8#1#0#0#9'TMainMenu'#9'MainMenu1'#4'l' - +'eft'#3'('#1#3'top'#3#8#1#0#9'TMenuItem'#7'mnuFile'#7'Caption'#6#5'&File'#0#9 - +'TMenuItem'#7'mnuOpen'#7'Caption'#6#8'&Open...'#7'OnClick'#7#12'mnuOpenClick' - +#0#0#9'TMenuItem'#9'mnuSaveAs'#7'Caption'#6#11'&Save as...'#7'OnClick'#7#14 - +'mnuSaveAsClick'#0#0#9'TMenuItem'#7'mnuQuit'#7'Caption'#6#5'&Quit'#7'OnClick' - +#7#12'mnuQuitClick'#0#0#0#0#0 + +'dth'#3#144#1#7'Caption'#6#7'fpsGrid'#12'ClientHeight'#3'?'#1#11'ClientWidth' + +#3#144#1#4'Menu'#7#9'MainMenu1'#8'ShowHint'#9#10'LCLVersion'#6#3'1.3'#0#6'TP' + +'anel'#6'Panel1'#4'Left'#2#0#6'Height'#2'7'#3'Top'#3#8#1#5'Width'#3#144#1#5 + +'Align'#7#8'alBottom'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'7'#11'Cl' + +'ientWidth'#3#144#1#8'TabOrder'#2#0#0#7'TButton'#15'btnPopulateGrid'#4'Left' + +#3#24#1#6'Height'#2#25#3'Top'#2#8#5'Width'#2'p'#7'Caption'#6#13'Populate Gri' + +'d'#7'OnClick'#7#20'btnPopulateGridClick'#8'TabOrder'#2#0#7'Visible'#8#0#0#9 + +'TCheckBox'#20'CbDisplayFixedColRow'#4'Left'#2#8#6'Height'#2#19#3'Top'#2#8#5 + +'Width'#3#130#0#7'Caption'#6#21'Display fixed col/row'#7'Checked'#9#7'OnClic' + +'k'#7#25'CbDisplayFixedColRowClick'#5'State'#7#9'cbChecked'#8'TabOrder'#2#1#0 + +#0#9'TCheckBox'#13'CbDisplayGrid'#4'Left'#2#8#6'Height'#2#19#3'Top'#2#29#5'W' + +'idth'#2'R'#7'Caption'#6#12'Display grid'#7'Checked'#9#7'OnClick'#7#18'CbDis' + +'playGridClick'#5'State'#7#9'cbChecked'#8'TabOrder'#2#2#0#0#0#12'TPageContro' + +'l'#12'PageControl1'#4'Left'#2#0#6'Height'#3#238#0#3'Top'#2#26#5'Width'#3#144 + +#1#10'ActivePage'#7#9'TabSheet1'#5'Align'#7#8'alClient'#8'TabIndex'#2#0#8'Ta' + +'bOrder'#2#1#8'OnChange'#7#18'PageControl1Change'#0#9'TTabSheet'#9'TabSheet1' + +#7'Caption'#6#6'Sheet1'#12'ClientHeight'#3#210#0#11'ClientWidth'#3#136#1#0#15 + +'TsWorksheetGrid'#15'sWorksheetGrid1'#4'Left'#2#0#6'Height'#3#210#0#3'Top'#2 + +#0#5'Width'#3#136#1#5'Align'#7#8'alClient'#7'Options'#11#15'goFixedVertLine' + +#15'goFixedHorzLine'#10'goVertLine'#10'goHorzLine'#13'goRangeSelect'#11'goCo' + +'lSizing'#15'goThumbTracking'#14'goSmoothScroll'#14'goCellEllipsis'#0#8'TabO' + +'rder'#2#0#10'TitleStyle'#7#8'tsNative'#0#0#0#0#8'TToolBar'#8'ToolBar1'#4'Le' + +'ft'#2#0#6'Height'#2#26#3'Top'#2#0#5'Width'#3#144#1#7'Caption'#6#8'ToolBar1' + +#11'EdgeBorders'#11#0#6'Images'#7#10'ImageList1'#8'TabOrder'#2#2#0#11'TToolB' + +'utton'#11'ToolButton1'#4'Left'#2#1#3'Top'#2#0#6'Action'#7#6'AcOpen'#0#0#11 + +'TToolButton'#11'ToolButton2'#4'Left'#2#24#3'Top'#2#0#6'Action'#7#8'AcSaveAs' + +#0#0#11'TToolButton'#11'ToolButton3'#4'Left'#2'4'#3'Top'#2#0#6'Action'#7#6'A' + +'cQuit'#0#0#11'TToolButton'#11'ToolButton5'#4'Left'#2'/'#3'Top'#2#0#5'Width' + +#2#5#7'Caption'#6#11'ToolButton5'#5'Style'#7#10'tbsDivider'#0#0#0#11'TOpenDi' + +'alog'#11'OpenDialog1'#10'DefaultExt'#6#4'.xls'#6'Filter'#6#192'Excel spread' + +'sheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlxs|LibreOffice/OpenO' + +'ffice spreadsheet (*.ods)|*.ods|Wikitable (pipes) (.wikitable_pipes)|.wikit' + +'able_pipes|All files (*.*)|*.*'#7'Options'#11#20'ofExtensionDifferent'#14'o' + +'fEnableSizing'#12'ofViewDetail'#0#4'left'#2'@'#3'top'#3#176#0#0#0#11'TSaveD' + +'ialog'#11'SaveDialog1'#10'DefaultExt'#6#4'.xls'#6'Filter'#6#185'Excel sprea' + +'dsheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlsx|LibreOffice/Open' + +'Office spreadsheet (*.ods)|*.ods|Wikitable (wikimedia) (.wikitable_wikimedi' + +'a)|*.wikitable_wikimedia'#7'Options'#11#20'ofExtensionDifferent'#14'ofEnabl' + +'eSizing'#12'ofViewDetail'#0#4'left'#3#176#0#3'top'#3#176#0#0#0#9'TMainMenu' + +#9'MainMenu1'#6'Images'#7#10'ImageList1'#4'left'#3' '#1#3'top'#3#176#0#0#9'T' + +'MenuItem'#7'mnuFile'#7'Caption'#6#5'&File'#0#9'TMenuItem'#7'mnuOpen'#6'Acti' + +'on'#7#6'AcOpen'#7'OnClick'#7#13'acOpenExecute'#0#0#9'TMenuItem'#9'mnuSaveAs' + +#6'Action'#7#8'AcSaveAs'#7'OnClick'#7#15'acSaveAsExecute'#0#0#9'TMenuItem'#9 + +'MenuItem1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#7'mnuQuit'#6'Action'#7#6'AcQu' + +'it'#7'OnClick'#7#13'acQuitExecute'#0#0#0#0#10'TImageList'#10'ImageList1'#4 + +'left'#3#176#0#3'top'#2'x'#6'Bitmap'#10#14#12#0#0'Li'#3#0#0#0#16#0#0#0#16#0#0 + +#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255 + +#255#255#0#234#195#157#255#230#191#150#255#228#187#146#255#228#187#146#255 + +#209#160'l'#245#208#158'm'#246#204#150'_'#218#196'yB~'#178'g<'#9#255#255#255 + +#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255 + +#255#255#0#229#190#150#255#255#255#254#255#253#243#233#255#253#243#234#255 + +#252#242#232#255#250#239#227#255#250#242#231#255#234#187#136#255#207#133'U' + +#179#180'i='#12#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255 + +#255#255#0#255#255#255#0#228#187#147#255#254#245#237#255#252#222#197#255#251 + +#224#199#255#249#220#194#255#245#211#180#255#254#249#243#255#250#226#196#255 + +#236#193#147#255#195'}H'#147#255#255#255#0#255#255#255#0#255#255#255#0#255 + +#255#255#0#255#255#255#0#255#255#255#0#228#187#146#255#254#246#240#255#252 + +#226#205#255#252#227#205#255#250#223#200#255#247#217#188#255#245#233#221#255 + +#250#243#235#255#251#248#243#255#202#131'S'#254#255#255#255#0#255#255#255#0 + +#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#228#187#146#255#254 + +#247#241#255#252#229#210#255#252#228#209#255#251#226#204#255#249#221#196#255 + +#246#215#187#255#243#209#175#255#250#239#228#255#204#135'X'#254'4'#180#217 + +#208'^'#194#225#250'`'#195#226#250'`'#195#226#250'`'#195#226#250'_'#195#226 + ,#250#228#187#145#255#255#247#242#255#254#231#213#255#254#231#213#255#253#229 + +#209#255#250#224#202#255#249#222#196#255#247#217#188#255#253#242#231#255#204 + +#135'W'#254'6'#179#218#248#253#254#254#255#254#255#255#255#254#254#255#255 + +#253#254#255#255#254#255#255#255#228#186#145#255#255#247#240#255#255#231#213 + +#255#253#231#214#255#253#230#212#255#252#228#208#255#251#227#203#255#250#220 + +#194#255#254#243#232#255#204#134'V'#254'5'#175#218#240#247#252#254#255#142 + +#228#248#255#145#222#245#255#159#224#245#255#172#225#246#255#202#132'R'#255 + +#255#247#241#255#255#233#217#255#255#234#219#255#255#233#217#255#255#231#215 + +#255#255#229#210#255#255#226#203#255#255#247#241#255#203#133'U'#254'6'#170 + +#218#242#241#250#253#255#148#222#245#255#147#220#244#255'd'#188#233#255'5' + +#148#218#255'5'#148#218#255'5'#148#218#255'5'#148#218#255'5'#148#218#255'5' + +#148#218#255'5'#148#218#255'5'#148#218#255'5'#148#218#255#251#246#239#255#204 + +#131'U'#254'5'#171#218#250#232#246#251#255'p'#188#231#255'U'#170#226#255'M' + +#165#224#255#145#201#235#255#250#243#239#255#253#254#253#255#255#253#252#255 + +#255#253#252#255#254#253#252#255#254#252#251#255#254#254#253#255'5'#148#218 + +#255#239#242#232#255#206#129'V'#255'7'#166#218#250#254#255#255#255#248#253 + +#255#255#246#253#255#255#245#252#255#255#243#252#254#255#154#228#244#255#154 + +#230#247#255#155#230#246#255#157#229#245#255#158#229#245#255#159#229#244#255 + +#218#243#248#255'5'#148#218#255#253#244#238#255#202#128'T'#249'6'#161#218#249 + +#246#252#254#255#148#229#248#255#147#229#248#255#147#229#248#255#145#229#248 + +#255#147#219#233#255#147#215#227#255#147#210#220#255#144#206#215#255#140#200 + +#207#255#134#193#198#255#201#216#214#255'5'#148#218#255#197'tD'#232#202#127 + +'S'#241'6'#154#218#248#242#250#253#255#148#230#248#255#146#229#248#255#144 + +#229#248#255#139#227#248#255#134#226#247#255#127#225#247#255'w'#222#246#255 + +'l'#220#246#255'^'#217#244#255'O'#213#243#255#204#242#251#255'5'#148#218#255 + +#255#255#255#0#255#255#255#0'5'#148#218#247#239#250#254#255#147#229#248#255 + +#143#228#248#255#137#227#248#255#130#225#247#255'z'#223#247#255'q'#222#246 + +#255'g'#219#245#255'['#216#244#255'M'#212#243#255'@'#209#242#255#202#242#251 + +#255'5'#148#218#255#255#255#255#0#255#255#255#0'3'#142#217#251#220#240#250 + +#255#152#225#246#255#149#224#246#255#146#223#246#255#142#222#245#255#137#220 + +#245#255#133#218#244#255#128#217#244#255'z'#215#243#255't'#213#243#255'p'#211 + +#242#255#194#234#248#255'5'#148#218#255#255#255#255#0#255#255#255#0','#134 + +#216#0'-'#136#216#247'-'#135#216#247'-'#136#216#247'-'#136#216#247'-'#136#216 + +#247'-'#136#216#247'-'#136#216#247'-'#136#216#247'-'#136#216#247'-'#136#216 + +#247'-'#135#216#247'-'#136#216#247','#134#216#0#255#255#255#0#255#255#255#0 + +#188'k6q'#188'k6'#144#188'k6'#204#188'k6'#238#188'k6'#250#187'k6'#254#187'k6' + +#255#187'j6'#255#187'j6'#255#188'l9'#255#189'n;'#255#187'm:'#255#187'k8'#239 + +#187'p>'#203#182'i5T'#255#255#255#0#188'k6'#155#246#224#209#255#247#224#209 + +#255#254#251#248#255#254#251#247#255#253#249#246#255#252#245#240#255#250#240 + +#234#255#251#242#237#255#253#249#246#255#253#250#247#255#251#241#235#255#248 + +#233#223#254#236#208#189#251#201#137'^'#236#181'i5c'#188'k6'#216#246#223#209 + +#255#233#170#128#255#254#250#246#255#253#250#246#255#200#140'd'#255#251#243 + +#238#255#251#241#234#255#252#246#242#255#254#251#248#255#252#246#241#255#249 + +#236#226#255#248#231#219#255#238#208#186#255#236#208#189#255#187'p>'#248#188 + +'k6'#240#246#223#208#255#232#168'~'#255#252#246#241#255#252#246#241#255#200 + +#140'd'#255#250#241#233#255#251#244#238#255#253#250#247#255#253#249#246#255 + +#250#240#232#255#248#232#221#255#247#230#219#255#225#163'z'#255#239#213#195 + +#255#183'i5'#254#188'k6'#250#245#221#204#255#231#168'~'#255#250#240#232#255 + +#250#240#232#255#201#141'f'#255#250#240#233#255#253#248#243#255#254#250#248 + +#255#252#244#239#255#249#233#223#255#247#231#219#255#247#229#217#255#224#162 + +'x'#255#231#194#169#255#182'h5'#255#187'k6'#254#244#220#201#255#231#167'}' + +#255#249#236#225#255#249#236#225#255#249#237#227#255#252#244#238#255#253#250 + +#247#255#253#247#243#255#250#237#229#255#247#231#219#255#247#229#217#255#246 + +#229#216#255#222#160'w'#255#228#190#164#255#180'g4'#255#187'k6'#255#244#217 + +#199#255#230#166'}'#255#200#140'd'#255#201#141'e'#255#201#142'g'#255#203#146 + +'l'#255#203#146'm'#255#202#144'i'#255#200#140'e'#255#200#140'd'#255#200#140 + +'d'#255#200#140'd'#255#218#156't'#255#225#186#159#255#179'f4'#255#187'j6'#255 + +#242#216#197#255#227#164'{'#255#227#163'z'#255#227#164'z'#255#226#164'{'#255 + +#226#163'{'#255#225#163'{'#255#225#162'y'#255#223#160'w'#255#222#159'v'#255 + +#221#158't'#255#219#156'r'#255#220#157't'#255#221#181#154#255#177'e4'#255#187 + +'j6'#255#242#213#194#255#227#163'z'#255#227#163'z'#255#226#163'{'#255#226#163 + +'{'#255#226#164'{'#255#225#162'y'#255#224#161'x'#255#222#160'w'#255#222#158 + +'u'#255#220#157't'#255#218#155's'#255#217#155's'#255#218#176#149#255#175'd3' + +#255#187'j6'#255#240#210#190#255#226#163'z'#255#226#163'z'#255#225#163'z'#255 + ,#226#163'{'#255#225#163'{'#255#224#161'x'#255#222#159'w'#255#221#159'v'#255 + +#220#157't'#255#217#155'r'#255#216#153'q'#255#214#153'p'#255#213#171#142#255 + +#173'c3'#255#186'j6'#255#239#208#187#255#226#162'z'#255#254#251#248#255#254 + +#251#248#255#254#251#248#255#254#251#248#255#254#251#248#255#254#251#248#255 + +#254#251#248#255#254#251#248#255#254#251#248#255#254#251#248#255#211#150'm' + +#255#210#167#138#255#171'b2'#255#187'k8'#255#239#206#184#255#225#162'y'#255 + +#254#250#247#255'b'#192#136#255'b'#192#136#255'b'#192#136#255'b'#192#136#255 + +'b'#192#136#255'b'#192#136#255'b'#192#136#255'b'#192#136#255#253#249#246#255 + +#207#147'j'#255#206#163#132#255#170'a2'#255#187'l8'#255#238#204#182#255#225 + +#162'z'#255#254#250#247#255#191#220#194#255#191#220#194#255#191#220#194#255 + +#191#220#194#255#191#220#194#255#191#220#194#255#191#220#194#255#191#220#194 + +#255#253#249#246#255#205#144'h'#255#204#158#129#255#168'a2'#255#186'k7'#254 + +#237#202#179#255#224#162'z'#255#254#250#247#255'b'#192#136#255'b'#192#136#255 + +'b'#192#136#255'b'#192#136#255'b'#192#136#255'b'#192#136#255'b'#192#136#255 + +'b'#192#136#255#253#249#246#255#202#141'e'#255#201#155'|'#255#167'`1'#254#186 + +'j5'#222#235#198#173#255#234#197#173#255#254#251#248#255#254#251#248#255#254 + +#251#248#255#254#251#248#255#254#251#248#255#254#251#248#255#254#251#248#255 + +#254#251#248#255#254#251#248#255#254#251#248#255#200#154'|'#255#199#152'y' + +#255#167'`1'#237#186'j6'#0#185'i5'#181#184'i5'#238#183'h5'#255#181'h5'#255 + +#180'g4'#255#178'f4'#255#176'e3'#255#174'd3'#255#172'c2'#255#170'b2'#255#169 + +'a2'#255#168'`1'#255#167'`1'#254#166'`1'#241#168'a1'#196#255#255#255#0#255 + +#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255 + +#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0 + +#255#255#255#0'm'#156#212#137'j'#154#210#251'f'#151#207#238#255#255#255#0#255 + +#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255 + +#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0'p'#158#214#219 + +'m'#156#212#255#133#177#218#255'Z'#145#185#255'`'#147#203#234#255#255#255#0 + +#255#255#255#0#128#128#128#255'~~~'#255'|||'#255'zzz'#255'www'#255'uuu'#255 + +'rrr'#255'q'#158#212#255'o'#158#214#255#135#178#220#255#171#211#232#255#169 + +#208#230#255'X'#144#184#255'Y'#142#198#234#255#255#255#0#255#255#255#0'}}}' + +#255#153#153#153#255#153#153#153#255#154#154#154#255#154#154#154#255#155#155 + +#155#255#155#155#155#255'o'#157#211#255#170#209#231#255#171#209#231#255#152 + +#199#225#255#145#194#222#255'V'#143#183#255'R'#137#193#234#255#255#255#0#255 + +#255#255#0'zzz'#255#153#153#153#255'R'#145'Y'#255#153#154#153#255#155#155#155 + +#255#156#156#156#255#156#156#156#255'l'#154#208#255#167#206#229#255#143#193 + +#223#255#137#189#220#255#139#189#220#255'S'#141#182#255'K'#132#188#234#255 + +#255#255#0#255#255#255#0'www'#255#154#154#154#255'='#138'E'#255'I'#138'O'#255 + +#156#156#156#255#157#157#157#255#157#157#157#255'f'#150#204#255#162#203#227 + +#255#137#189#220#255#131#185#218#255#132#185#218#255'Q'#139#181#255'C~'#182 + +#234'D'#148'M'#255'B'#145'K'#255'?'#141'H'#255'='#137'E'#255']'#164'e'#255'Z' + +#160'a'#255'E'#131'K'#255#158#158#158#255#158#158#158#255'`'#146#201#255#158 + +#199#226#255#131#184#218#255'}'#180#215#255'~'#179#215#255'O'#137#180#255';y' + +#177#234'A'#144'J'#255#148#210#159#255#145#208#154#255#141#205#150#255#137 + +#203#146#255#132#200#141#255'Q'#152'X'#255'A|F'#255#159#159#159#255'Z'#142 + +#196#255#152#195#224#255'|'#179#215#255't'#175#214#255'^'#196#237#255'K'#136 + +#179#255'4s'#171#234'>'#139'F'#255#143#206#153#255'}'#198#135#255'x'#195#129 + +#255's'#192'|'#255't'#192'|'#255'y'#194#129#255'I'#144'O'#255'T'#127'W'#255 + +'T'#137#191#255#148#191#221#255'u'#173#212#255'c'#184#225#255'K'#212#255#255 + +'B'#139#184#255',n'#166#234';'#135'B'#255#137#203#146#255#132#200#141#255#128 + +#198#136#255'{'#195#131#255'w'#193#127#255'G'#143'M'#255';t?'#255#161#161#161 + +#255'L'#132#186#255#141#187#219#255'n'#168#209#255'f'#166#209#255'_'#180#223 + +#255'G'#133#177#255'%i'#161#234'7'#130'>'#255'4~;'#255'1y7'#255'.u4'#255'I' + +#145'P'#255'F'#143'L'#255'9s='#255#161#161#161#255#162#162#162#255'E~'#180 + +#255#136#183#217#255'g'#163#207#255'a'#158#204#255'c'#159#204#255'E'#131#177 + +#255#31'd'#156#234#255#255#255#0#255#255#255#0'```'#255#160#160#160#255'=vA' + +#255'6q9'#255#162#162#162#255#162#162#162#255#163#163#163#255'=y'#176#255#130 + +#179#215#255'b'#159#204#255'Z'#154#201#255'^'#155#202#255'C'#129#175#255#25 + +'`'#152#234#255#255#255#0#255#255#255#0'\\\'#255#161#161#161#255'~'#173#255#12'W'#143#234#255#255#255#0#255#255#255#0 + +#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255 + +#255#255#0#255#255#255#0#29'c'#155#22#25'`'#152'9'#20']'#149'b'#16'Z'#146#136 + +#13'X'#144#164#19'\'#146#252#12'W'#143#237#0#0#11'TActionList'#11'ActionList' + +'1'#4'left'#3#176#0#3'top'#2'@'#0#7'TAction'#6'AcOpen'#7'Caption'#6#7'Open..' + +'.'#10'ImageIndex'#2#0#9'OnExecute'#7#13'acOpenExecute'#0#0#7'TAction'#8'AcS' + +'aveAs'#7'Caption'#6#10'Save as...'#10'ImageIndex'#2#1#9'OnExecute'#7#15'acS' + +'aveAsExecute'#0#0#7'TAction'#6'AcQuit'#7'Caption'#6#4'Quit'#10'ImageIndex'#2 + +#2#9'OnExecute'#7#13'acQuitExecute'#0#0#0#0 ]); diff --git a/components/fpspreadsheet/examples/fpsgrid/mainform.pas b/components/fpspreadsheet/examples/fpsgrid/mainform.pas index e3d9f9add..33f132eea 100644 --- a/components/fpspreadsheet/examples/fpsgrid/mainform.pas +++ b/components/fpspreadsheet/examples/fpsgrid/mainform.pas @@ -6,7 +6,7 @@ interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, Menus, + StdCtrls, Menus, ExtCtrls, ComCtrls, ActnList, fpspreadsheetgrid, fpspreadsheet, fpsallformats; type @@ -14,19 +14,38 @@ type { TForm1 } TForm1 = class(TForm) - buttonPopulateGrid: TButton; + AcOpen: TAction; + AcSaveAs: TAction; + AcQuit: TAction; + ActionList1: TActionList; + btnPopulateGrid: TButton; + CbDisplayFixedColRow: TCheckBox; + CbDisplayGrid: TCheckBox; + ImageList1: TImageList; MainMenu1: TMainMenu; + MenuItem1: TMenuItem; mnuFile: TMenuItem; mnuOpen: TMenuItem; mnuQuit: TMenuItem; mnuSaveAs: TMenuItem; OpenDialog1: TOpenDialog; + PageControl1: TPageControl; + Panel1: TPanel; SaveDialog1: TSaveDialog; sWorksheetGrid1: TsWorksheetGrid; - procedure buttonPopulateGridClick(Sender: TObject); - procedure mnuOpenClick(Sender: TObject); - procedure mnuQuitClick(Sender: TObject); - procedure mnuSaveAsClick(Sender: TObject); + TabSheet1: TTabSheet; + ToolBar1: TToolBar; + ToolButton1: TToolButton; + ToolButton2: TToolButton; + ToolButton3: TToolButton; + ToolButton5: TToolButton; + procedure btnPopulateGridClick(Sender: TObject); + procedure CbDisplayFixedColRowClick(Sender: TObject); + procedure CbDisplayGridClick(Sender: TObject); + procedure acOpenExecute(Sender: TObject); + procedure acQuitExecute(Sender: TObject); + procedure acSaveAsExecute(Sender: TObject); + procedure PageControl1Change(Sender: TObject); private { private declarations } public @@ -38,42 +57,76 @@ var implementation +uses + Grids; + { TForm1 } -procedure TForm1.buttonPopulateGridClick(Sender: TObject); +procedure TForm1.btnPopulateGridClick(Sender: TObject); // Populate grid with some demo data var - lWorksheet: TsWorksheet; + lCell: PCell; begin - lWorksheet := TsWorksheet.Create; - try - lWorksheet.WriteUTF8Text(2, 2, 'Algo'); - sWorksheetGrid1.LoadFromWorksheet(lWorksheet); - finally - lWorksheet.Free; - end; + // create a cell (2,2) if not yet available + lCell := sWorksheetGrid1.Worksheet.GetCell(2, 2); + sWorksheetGrid1.Worksheet.WriteUTF8Text(2, 2, 'Algo'); + sWorksheetGrid1.Invalidate; end; -procedure TForm1.mnuOpenClick(Sender: TObject); +procedure TForm1.CbDisplayFixedColRowClick(Sender: TObject); +begin + sWorksheetGrid1.DisplayFixedColRow := CbDisplayFixedColRow.Checked; +end; + +procedure TForm1.CbDisplayGridClick(Sender: TObject); +begin + if CbDisplayGrid.Checked then + sWorksheetGrid1.Options := sWorksheetGrid1.Options + [goHorzLine, goVertLine] + else + sWorksheetGrid1.Options := sWorksheetGrid1.Options - [goHorzLine, goVertLine]; +end; + +procedure TForm1.acOpenExecute(Sender: TObject); // Loads first worksheet from file into grid +var + pages: TStrings; + i: Integer; begin if OpenDialog1.Execute then begin sWorksheetGrid1.LoadFromSpreadsheetFile(OpenDialog1.FileName); + Caption := Format('fpsGrid - %s', [OpenDialog1.Filename]); + + // Create a tab in the pagecontrol for each worksheet contained in the workbook + // This would be easer with a TTabControl. This has display issues, though. + pages := TStringList.Create; + try + sWorksheetGrid1.GetSheets(pages); + sWorksheetGrid1.Parent := PageControl1.Pages[0]; + while PageControl1.PageCount > pages.Count do PageControl1.Pages[1].Free; + while PageControl1.PageCount < pages.Count do PageControl1.AddTabSheet; + for i:=0 to PageControl1.PageCount-1 do + PageControl1.Pages[i].Caption := pages[i]; + finally + pages.Free; + end; end; end; -procedure TForm1.mnuQuitClick(Sender: TObject); +procedure TForm1.acQuitExecute(Sender: TObject); begin Close; end; -procedure TForm1.mnuSaveAsClick(Sender: TObject); +procedure TForm1.acSaveAsExecute(Sender: TObject); // Saves sheet in grid to file, overwriting existing file var lWorkBook: TsWorkbook; lWorkSheet:TsWorksheet; begin + ShowMessage('Not implemented...'); + exit; + if SaveDialog1.Execute then begin lWorkBook := TsWorkBook.Create; @@ -87,6 +140,12 @@ begin end; end; +procedure TForm1.PageControl1Change(Sender: TObject); +begin + sWorksheetGrid1.Parent := PageControl1.Pages[PageControl1.ActivePageIndex]; + sWorksheetGrid1.SelectSheetByIndex(PageControl1.ActivePageIndex); +end; + initialization {$I mainform.lrs} diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index 362826acd..dd8059a3c 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -216,7 +216,7 @@ type } TCell = record - Col: Byte; // zero-based + Col: Cardinal; // zero-based Row: Cardinal; // zero-based ContentType: TCellContentType; { Possible values for the cells } diff --git a/components/fpspreadsheet/fpspreadsheetgrid.pas b/components/fpspreadsheet/fpspreadsheetgrid.pas index 448eff91c..2964f5538 100644 --- a/components/fpspreadsheet/fpspreadsheetgrid.pas +++ b/components/fpspreadsheet/fpspreadsheetgrid.pas @@ -19,22 +19,35 @@ type { TsCustomWorksheetGrid } - TsCustomWorksheetGrid = class(TCustomStringGrid) + TsCustomWorksheetGrid = class(TCustomDrawGrid) private + FWorkbook: TsWorkbook; FWorksheet: TsWorksheet; FDisplayFixedColRow: Boolean; + function CalcColWidth(AWidth: Single): Integer; procedure SetDisplayFixedColRow(const AValue: Boolean); { Private declarations } protected { Protected declarations } + procedure DoPrepareCanvas(ACol, ARow: Integer; AState: TGridDrawState); override; + procedure DrawCellGrid(aCol,aRow: Integer; aRect: TRect; aState: TGridDrawState); override; + procedure DrawTextInCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); override; + function GetCellText(ACol, ARow: Integer): String; + procedure Loaded; override; + procedure Setup; public { methods } constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure GetSheets(const ASheets: TStrings); procedure LoadFromWorksheet(AWorksheet: TsWorksheet); procedure LoadFromSpreadsheetFile(AFileName: string; AFormat: TsSpreadsheetFormat; AWorksheetIndex: Integer = 0); overload; procedure LoadFromSpreadsheetFile(AFileName: string; AWorksheetIndex: Integer = 0); overload; procedure SaveToWorksheet(AWorksheet: TsWorksheet); + procedure SelectSheetByIndex(AIndex: Integer); property DisplayFixedColRow: Boolean read FDisplayFixedColRow write SetDisplayFixedColRow; + property Worksheet: TsWorksheet read FWorksheet; + property Workbook: TsWorkbook read FWorkbook; end; { TsWorksheetGrid } @@ -52,7 +65,7 @@ type property BorderStyle; property Color; property ColCount; - property Columns; + //property Columns; property Constraints; property DefaultColWidth; property DefaultDrawing; @@ -88,7 +101,6 @@ type property VisibleColCount; property VisibleRowCount; - property OnBeforeSelection; property OnChangeBounds; property OnClick; @@ -140,115 +152,230 @@ procedure Register; implementation +uses + fpsUtils; + procedure Register; begin RegisterComponents('Additional',[TsWorksheetGrid]); end; -const - INT_FPSCOLROW_TO_GRIDCOLROW_WITH_FIXEDCOLROW = 2; - INT_FPSCOLROW_TO_GRIDCOLROW = 1; { TsCustomWorksheetGrid } -procedure TsCustomWorksheetGrid.SetDisplayFixedColRow(const AValue: Boolean); -var - x: Integer; -begin - if AValue = FDisplayFixedColRow then Exit; - - FDisplayFixedColRow := AValue; - - if AValue then - begin - for x := 1 to ColCount - 1 do - SetCells(x, 0, 'A'); - for x := 1 to RowCount - 1 do - SetCells(0, x, IntToStr(x)); - end; -end; - constructor TsCustomWorksheetGrid.Create(AOwner: TComponent); begin inherited Create(AOwner); - - FDisplayFixedColRow := False; - FixedCols := 0; - FixedRows := 0; + FDisplayFixedColRow := true; end; -procedure TsCustomWorksheetGrid.LoadFromWorksheet(AWorksheet: TsWorksheet); -var - x, lRow, lCol: Integer; - lStr: string; - lCell: PCell; +destructor TsCustomWorksheetGrid.Destroy; begin - FWorksheet := AWorksheet; + FreeAndNil(FWorkbook); + inherited Destroy; +end; - { First get the size of the table } - if FWorksheet.GetCellCount = 0 then - begin - ColCount := 0; - RowCount := 0; - end - else - begin - if DisplayFixedColRow then - begin - ColCount := FWorksheet.GetLastColNumber() + INT_FPSCOLROW_TO_GRIDCOLROW_WITH_FIXEDCOLROW; - RowCount := FWorksheet.GetLastRowNumber() + INT_FPSCOLROW_TO_GRIDCOLROW_WITH_FIXEDCOLROW; +function TsCustomWorksheetGrid.CalcColWidth(AWidth: Single): Integer; +var + w0: Integer; +begin + w0 := Canvas.TextWidth('0'); + Result := Round(AWidth * w0); +end; + +procedure TsCustomWorksheetGrid.DoPrepareCanvas(ACol, ARow: Integer; + AState: TGridDrawState); +var + ts: TTextStyle; + lCell: PCell; + r, c: Integer; +begin + ts := Canvas.TextStyle; + if FDisplayFixedColRow then begin + // Formatting of row and column headers + if ARow = 0 then + ts.Alignment := taCenter + else + if ACol = 0 then + ts.Alignment := taRightJustify; + end; + if FWorksheet <> nil then begin + r := ARow - FixedRows; + c := ACol - FixedCols; + lCell := FWorksheet.FindCell(r, c); + if lCell <> nil then begin + // Default alignment of number is right-justify + if lCell^.ContentType = cctNumber then + ts.Alignment := taRightJustify; + end; + end; + Canvas.TextStyle := ts; + + inherited DoPrepareCanvas(ACol, ARow, AState); +end; + +procedure TsCustomWorksheetGrid.DrawCellGrid(ACol, ARow: Integer; ARect: TRect; + AState: TGridDrawState); +var + lCell: PCell; + r, c: Integer; +begin + inherited; + + if FWorksheet = nil then exit; + + r := ARow - FixedRows; + c := ACol - FixedCols; + lCell := FWorksheet.FindCell(r, c); + if (lCell <> nil) and (uffBorder in lCell^.UsedFormattingFields) then begin + Canvas.Pen.Style := psSolid; + Canvas.Pen.Color := clBlack; + if (cbNorth in lCell^.Border) then + Canvas.Line(ARect.Left, ARect.Top, ARect.Right, ARect.Top) + else + if (cbWest in lCell^.Border) then + Canvas.Line(ARect.Left, ARect.Top, ARect.Left, ARect.Bottom) + else + if (cbEast in lCell^.Border) then + Canvas.Line(ARect.Right-1, ARect.Top, ARect.Right-1, ARect.Bottom) + else + if (cbSouth in lCell^.Border) then + Canvas.Line(ARect.Left, ARect.Bottom-1, ARect.Right, ARect.Bottom-1) + end; +end; + +procedure TsCustomWorksheetGrid.DrawTextInCell(ACol, ARow: Integer; ARect: TRect; + AState: TGridDrawState); +begin + DrawCellText(aCol, aRow, aRect, aState, GetCellText(ACol,ARow)); +end; + +function TsCustomWorksheetGrid.GetCellText(ACol, ARow: Integer): String; +var + lCell: PCell; + r, c: Integer; +begin + Result := ''; + + if FDisplayFixedColRow then begin + // Titles + if (ARow = 0) and (ACol = 0) then + exit; + if (ARow = 0) then begin + Result := GetColString(ACol-FixedCols); + exit; end else - begin - ColCount := FWorksheet.GetLastColNumber() + INT_FPSCOLROW_TO_GRIDCOLROW; - RowCount := FWorksheet.GetLastRowNumber() + INT_FPSCOLROW_TO_GRIDCOLROW; + if (ACol = 0) then begin + Result := IntToStr(ARow); + exit; end; end; - { Now copy the contents } - - lCell := FWorksheet.GetFirstCell(); - for x := 0 to FWorksheet.GetCellCount() - 1 do - begin - lCol := lCell^.Col; - lRow := lCell^.Row; - lStr := FWorksheet.ReadAsUTF8Text(lRow, lCol); - - if DisplayFixedColRow then - SetCells(lCol + 1, lRow + 1, lStr) - else - SetCells(lCol, lRow, lStr); - - lCell := FWorksheet.GetNextCell(); + if FWorksheet <> nil then begin + r := ARow - FixedRows; + c := ACol - FixedCols; + lCell := FWorksheet.FindCell(r, c); + if lCell <> nil then + Result := FWorksheet.ReadAsUTF8Text(r, c); end; end; +procedure TsCustomWorksheetGrid.GetSheets(const ASheets: TStrings); +var + i: Integer; +begin + ASheets.Clear; + if Assigned(FWorkbook) then + for i:=0 to FWorkbook.GetWorksheetCount-1 do + ASheets.Add(FWorkbook.GetWorksheetByIndex(i).Name); +end; + +procedure TsCustomWorksheetGrid.Loaded; +begin + inherited; + Setup; +end; + +procedure TsCustomWorksheetGrid.SetDisplayFixedColRow(const AValue: Boolean); +begin + if AValue = FDisplayFixedColRow then Exit; + + FDisplayFixedColRow := AValue; + Setup; +end; + +procedure TsCustomWorksheetGrid.Setup; +var + i: Integer; + lCol: PCol; +begin + if (FWorksheet = nil) or (FWorksheet.GetCellCount = 0) then begin + if FDisplayFixedColRow then begin + ColCount := 2; + RowCount := 2; + FixedCols := 1; + FixedRows := 1; + ColWidths[0] := Canvas.TextWidth(' 999999 '); + end else begin + FixedCols := 0; + FixedRows := 0; + ColCount := 0; + RowCount := 0; + end; + end else + if FDisplayFixedColRow then begin + ColCount := FWorksheet.GetLastColNumber + 2; + RowCount := FWorksheet.GetLastRowNumber + 2; + FixedCols := 1; + FixedRows := 1; + ColWidths[0] := Canvas.TextWidth(' 999999 '); + // Setup column widths + for i := FixedCols to ColCount-1 do begin + lCol := FWorksheet.FindCol(i - FixedCols); + if (lCol <> nil) then + ColWidths[i] := CalcColWidth(lCol^.Width) + else + ColWidths[i] := DefaultColWidth; + end; + end else begin + ColCount := FWorksheet.GetLastColNumber + 1; + RowCount := FWorksheet.GetLastRowNumber + 1; + FixedCols := 0; + FixedRows := 0; + for i := 0 to ColCount-1 do begin + lCol := FWorksheet.FindCol(i); + if (lCol <> nil) then + ColWidths[i] := CalcColWidth(lCol^.Width) + else + ColWidths[i] := DefaultColWidth; + end; + end; + Invalidate; +end; + +procedure TsCustomWorksheetGrid.LoadFromWorksheet(AWorksheet: TsWorksheet); +begin + FWorksheet := AWorksheet; + Setup; +end; + procedure TsCustomWorksheetGrid.LoadFromSpreadsheetFile(AFileName: string; AFormat: TsSpreadsheetFormat; AWorksheetIndex: Integer); -var - lWorkbook: TsWorkbook; begin - lWorkbook := TsWorkbook.Create; - try - lWorkbook.ReadFromFile(AFileName, AFormat); - LoadFromWorksheet(lWorkbook.GetWorksheetByIndex(AWorksheetIndex)); - finally - lWorkbook.Free; - end; + FreeAndNil(FWorkbook); + FWorkbook := TsWorkbook.Create; + FWorkbook.ReadFromFile(AFileName, AFormat); + LoadFromWorksheet(FWorkbook.GetWorksheetByIndex(AWorksheetIndex)); end; procedure TsCustomWorksheetGrid.LoadFromSpreadsheetFile(AFileName: string; AWorksheetIndex: Integer); -var - lWorkbook: TsWorkbook; begin - lWorkbook := TsWorkbook.Create; - try - lWorkbook.ReadFromFile(AFileName); - LoadFromWorksheet(lWorkbook.GetWorksheetByIndex(AWorksheetIndex)); - finally - lWorkbook.Free; - end; + FreeAndNil(FWorkbook); + FWorkbook := TsWorkbook.Create; + FWorkbook.ReadFromFile(AFilename); + LoadFromWorksheet(FWorkbook.GetWorksheetByIndex(AWorksheetIndex)); end; procedure TsCustomWorksheetGrid.SaveToWorksheet(AWorksheet: TsWorksheet); @@ -268,4 +395,9 @@ begin end; end; +procedure TsCustomWorksheetGrid.SelectSheetByIndex(AIndex: Integer); +begin + LoadFromWorksheet(FWorkbook.GetWorksheetByIndex(AIndex)); +end; + end. diff --git a/components/fpspreadsheet/fpsutils.pas b/components/fpspreadsheet/fpsutils.pas index b55909984..c63925141 100644 --- a/components/fpspreadsheet/fpsutils.pas +++ b/components/fpspreadsheet/fpsutils.pas @@ -49,6 +49,9 @@ function ParseCellRowString(const AStr: string; var AResult: Integer): Boolean; function ParseCellColString(const AStr: string; var AResult: Integer): Boolean; + +function GetColString(AColIndex: Integer): String; + function UTF8TextToXMLText(AText: ansistring): ansistring; implementation @@ -371,6 +374,26 @@ begin Result := True; end; +function Letter(AValue: Integer): char; +begin + Result := Char(AValue + ord('A')); +end; + +function GetColString(AColIndex: Integer): String; +begin + if AColIndex < 26 then + Result := Letter(AColIndex) + else + if AColIndex < 26*26 then + Result := Letter(AColIndex div 26) + Letter(AColIndex mod 26) + else + if AColIndex < 26*26*26 then + Result := Letter(AColIndex div (26*26)) + Letter((AColIndex mod (26*26)) div 26) + + Letter(AColIndex mod (26*26*26)) + else + Result := 'too big'; +end; + {In XML files some chars must be translated} function UTF8TextToXMLText(AText: ansistring): ansistring; var diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas index 494fc7d0c..2f95e2b6b 100755 --- a/components/fpspreadsheet/xlsbiff8.pas +++ b/components/fpspreadsheet/xlsbiff8.pas @@ -2382,18 +2382,17 @@ var xf: TXFRecord; begin AStream.ReadBuffer(xf, SizeOf(xf)); -{ xf.FormatIndex := WordLEToN(xf.FormatIndex); - xf.XFType_CellProt_ParentStyleXF := WordLEToN(xf.XFType_CellProt_ParentStyleXF); - } + lData := TXFRecordData.Create; + // Format index lData.FormatIndex := WordLEToN(xf.FormatIndex); // Cell borders xf.Border_Background_1 := DWordLEToN(xf.Border_Background_1); - xf.Border_Background_2 := DWordLEToN(xf.Border_Background_2); - xf.Border_Background_3 := WordLEToN(xf.Border_Background_3); lData.Borders := []; + // the 4 masked bits encode the line style of the border line. 0 = no line + // We ignore the line style here. --> check against "no line" if xf.Border_Background_1 and $0000000F <> 0 then Include(lData.Borders, cbWest); if xf.Border_Background_1 and $000000F0 <> 0 then @@ -2403,53 +2402,6 @@ begin if xf.Border_Background_1 and $0000F000 <> 0 then Include(lData.Borders, cbSouth); - (* - // Record XF, BIFF8: - // Offset Size Contents - // 0 2 Index to FONT record (➜5.45)) - WordLEtoN(AStream.ReadWord); - - // 2 2 Index to FORMAT record (➜5.49)) - lData.FormatIndex := WordLEtoN(AStream.ReadWord); - - // 4 2 XF type, cell protection, and parent style XF - // Bit Mask Contents - // 2-0 0007H XF_TYPE_PROT – XF type, cell protection (see above) - // 15-4 FFF0H Index to parent style XF (always FFFH in style XFs) - WordLEtoN(AStream.ReadWord); - - // 6 1 Alignment and text break: - // Bit Mask Contents - // 2-0 07H XF_HOR_ALIGN – Horizontal alignment (see above) - // 3 08H 1 = Text is wrapped at right border - // 6-4 70H XF_VERT_ALIGN – Vertical alignment (see above) - // 7 80H 1 = Justify last line in justified or distibuted text - b - - { Offset Size Contents - 4 2 XF type, cell protection, and parent style XF: - Bit Mask Contents - 2-0 0007H XF_TYPE_PROT – XF type, cell protection (see above) - 15-4 FFF0H Index to parent style XF (always FFFH in style XFs) - - 6 1 Alignment and text break: - Bit Mask Contents - 2-0 07H XF_HOR_ALIGN – Horizontal alignment (see above) - 3 08H 1 = Text is wrapped at right border - 6-4 70H XF_VERT_ALIGN – Vertical alignment (see above) - 7 80H 1 = Justify last line in justified or distibuted text - 7 1 XF_ROTATION: Text rotation angle (see above) - 8 1 Indentation, shrink to cell size, and text direction: - Bit Mask Contents - 3-0 0FH Indent level - 4 10H 1 = Shrink content to fit into cell - 7-6 C0H Text direction: - 0 = According to context - 35 - ; 1 = Left-to-right; 2 = Right-to-left - 9 1 Flags for used attribute groups: - ....} - *) // Add the XF to the list FXFList.Add(lData); end;